mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Merge branch '1828-self-destruct-timer-private-messages' into '804-self-destructing-messages'
Update messaging client to include a self-destruct timer in each message See merge request briar/briar!1299
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
package org.briarproject.bramble.api.autodelete;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.DAYS;
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
|
||||||
|
public interface AutoDeleteConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum valid auto-delete timer duration in milliseconds.
|
||||||
|
*/
|
||||||
|
long MIN_AUTO_DELETE_TIMER_MS = MINUTES.toMillis(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum valid auto-delete timer duration in milliseconds.
|
||||||
|
*/
|
||||||
|
long MAX_AUTO_DELETE_TIMER_MS = DAYS.toMillis(365);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder value indicating that a message has no auto-delete timer.
|
||||||
|
* This value should not be sent over the wire - send null instead.
|
||||||
|
*/
|
||||||
|
long NO_AUTO_DELETE_TIMER = -1;
|
||||||
|
}
|
||||||
@@ -140,6 +140,7 @@ import static org.briarproject.briar.android.util.UiUtils.getBulbTransitionName;
|
|||||||
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
||||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_ATTACHMENTS_PER_MESSAGE;
|
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_ATTACHMENTS_PER_MESSAGE;
|
||||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH;
|
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -273,15 +274,11 @@ public class ConversationActivity extends BriarActivity
|
|||||||
ImagePreview imagePreview = findViewById(R.id.imagePreview);
|
ImagePreview imagePreview = findViewById(R.id.imagePreview);
|
||||||
sendController = new TextAttachmentController(textInputView,
|
sendController = new TextAttachmentController(textInputView,
|
||||||
imagePreview, this, viewModel);
|
imagePreview, this, viewModel);
|
||||||
viewModel.hasImageSupport().observe(this, new Observer<Boolean>() {
|
observeOnce(viewModel.getPrivateMessageFormat(), this, format -> {
|
||||||
@Override
|
if (format != TEXT_ONLY) {
|
||||||
public void onChanged(@Nullable Boolean hasSupport) {
|
// TODO: remove cast when removing feature flag
|
||||||
if (hasSupport != null && hasSupport) {
|
((TextAttachmentController) sendController)
|
||||||
// TODO: remove cast when removing feature flag
|
.setImagesSupported();
|
||||||
((TextAttachmentController) sendController)
|
|
||||||
.setImagesSupported();
|
|
||||||
viewModel.hasImageSupport().removeObserver(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -657,8 +654,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
supportFinishAfterTransition();
|
supportFinishAfterTransition();
|
||||||
}
|
}
|
||||||
} else if (e instanceof ConversationMessageReceivedEvent) {
|
} else if (e instanceof ConversationMessageReceivedEvent) {
|
||||||
ConversationMessageReceivedEvent p =
|
ConversationMessageReceivedEvent<?> p =
|
||||||
(ConversationMessageReceivedEvent) e;
|
(ConversationMessageReceivedEvent<?>) e;
|
||||||
if (p.getContactId().equals(contactId)) {
|
if (p.getContactId().equals(contactId)) {
|
||||||
LOG.info("Message received, adding");
|
LOG.info("Message received, adding");
|
||||||
onNewConversationMessage(p.getMessageHeader());
|
onNewConversationMessage(p.getMessageHeader());
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.briarproject.briar.api.messaging.AttachmentHeader;
|
|||||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageFormat;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
||||||
|
|
||||||
@@ -52,17 +53,20 @@ import androidx.lifecycle.Transformations;
|
|||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
|
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
|
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class ConversationViewModel extends AndroidViewModel
|
public class ConversationViewModel extends AndroidViewModel
|
||||||
implements EventListener, AttachmentManager {
|
implements EventListener, AttachmentManager {
|
||||||
|
|
||||||
private static Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(ConversationViewModel.class.getName());
|
getLogger(ConversationViewModel.class.getName());
|
||||||
|
|
||||||
private static final String SHOW_ONBOARDING_IMAGE =
|
private static final String SHOW_ONBOARDING_IMAGE =
|
||||||
@@ -89,7 +93,7 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
private final LiveData<String> contactName =
|
private final LiveData<String> contactName =
|
||||||
Transformations.map(contact, UiUtils::getContactDisplayName);
|
Transformations.map(contact, UiUtils::getContactDisplayName);
|
||||||
private final LiveData<GroupId> messagingGroupId;
|
private final LiveData<GroupId> messagingGroupId;
|
||||||
private final MutableLiveData<Boolean> imageSupport =
|
private final MutableLiveData<PrivateMessageFormat> privateMessageFormat =
|
||||||
new MutableLiveData<>();
|
new MutableLiveData<>();
|
||||||
private final MutableLiveEvent<Boolean> showImageOnboarding =
|
private final MutableLiveEvent<Boolean> showImageOnboarding =
|
||||||
new MutableLiveEvent<>();
|
new MutableLiveEvent<>();
|
||||||
@@ -210,11 +214,8 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
// messagingGroupId is loaded with the contact
|
// messagingGroupId is loaded with the contact
|
||||||
observeForeverOnce(messagingGroupId, groupId -> {
|
observeForeverOnce(messagingGroupId, groupId -> {
|
||||||
requireNonNull(groupId);
|
requireNonNull(groupId);
|
||||||
observeForeverOnce(imageSupport, hasImageSupport -> {
|
observeForeverOnce(privateMessageFormat, format ->
|
||||||
requireNonNull(hasImageSupport);
|
createMessage(groupId, text, headers, timestamp, format));
|
||||||
createMessage(groupId, text, headers, timestamp,
|
|
||||||
hasImageSupport);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,10 +245,10 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void checkFeaturesAndOnboarding(ContactId c) throws DbException {
|
private void checkFeaturesAndOnboarding(ContactId c) throws DbException {
|
||||||
// check if images are supported
|
// check if images and auto-deletion are supported
|
||||||
boolean imagesSupported = db.transactionWithResult(true, txn ->
|
PrivateMessageFormat format = db.transactionWithResult(true, txn ->
|
||||||
messagingManager.contactSupportsImages(txn, c));
|
messagingManager.getContactMessageFormat(txn, c));
|
||||||
imageSupport.postValue(imagesSupported);
|
privateMessageFormat.postValue(format);
|
||||||
|
|
||||||
// check if introductions are supported
|
// check if introductions are supported
|
||||||
Collection<Contact> contacts = contactManager.getContacts();
|
Collection<Contact> contacts = contactManager.getContacts();
|
||||||
@@ -256,7 +257,7 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
|
|
||||||
// we only show one onboarding dialog at a time
|
// we only show one onboarding dialog at a time
|
||||||
Settings settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
|
Settings settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
|
||||||
if (imagesSupported &&
|
if (format != TEXT_ONLY &&
|
||||||
settings.getBoolean(SHOW_ONBOARDING_IMAGE, true)) {
|
settings.getBoolean(SHOW_ONBOARDING_IMAGE, true)) {
|
||||||
onOnboardingShown(SHOW_ONBOARDING_IMAGE);
|
onOnboardingShown(SHOW_ONBOARDING_IMAGE);
|
||||||
showImageOnboarding.postEvent(true);
|
showImageOnboarding.postEvent(true);
|
||||||
@@ -277,15 +278,19 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
@UiThread
|
@UiThread
|
||||||
private void createMessage(GroupId groupId, @Nullable String text,
|
private void createMessage(GroupId groupId, @Nullable String text,
|
||||||
List<AttachmentHeader> headers, long timestamp,
|
List<AttachmentHeader> headers, long timestamp,
|
||||||
boolean hasImageSupport) {
|
PrivateMessageFormat format) {
|
||||||
try {
|
try {
|
||||||
PrivateMessage pm;
|
PrivateMessage pm;
|
||||||
if (hasImageSupport) {
|
if (format == TEXT_ONLY) {
|
||||||
|
pm = privateMessageFactory.createLegacyPrivateMessage(
|
||||||
|
groupId, timestamp, requireNonNull(text));
|
||||||
|
} else if (format == TEXT_IMAGES) {
|
||||||
pm = privateMessageFactory.createPrivateMessage(groupId,
|
pm = privateMessageFactory.createPrivateMessage(groupId,
|
||||||
timestamp, text, headers);
|
timestamp, text, headers);
|
||||||
} else {
|
} else {
|
||||||
pm = privateMessageFactory.createLegacyPrivateMessage(
|
// TODO: Look up auto-delete timer
|
||||||
groupId, timestamp, requireNonNull(text));
|
pm = privateMessageFactory.createPrivateMessage(groupId,
|
||||||
|
timestamp, text, headers, NO_AUTO_DELETE_TIMER);
|
||||||
}
|
}
|
||||||
storeMessage(pm);
|
storeMessage(pm);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
@@ -305,7 +310,8 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
PrivateMessageHeader h = new PrivateMessageHeader(
|
PrivateMessageHeader h = new PrivateMessageHeader(
|
||||||
message.getId(), message.getGroupId(),
|
message.getId(), message.getGroupId(),
|
||||||
message.getTimestamp(), true, true, false, false,
|
message.getTimestamp(), true, true, false, false,
|
||||||
m.hasText(), m.getAttachmentHeaders());
|
m.hasText(), m.getAttachmentHeaders(),
|
||||||
|
m.getAutoDeleteTimer());
|
||||||
// TODO add text to cache when available here
|
// TODO add text to cache when available here
|
||||||
addedHeader.postEvent(h);
|
addedHeader.postEvent(h);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
@@ -330,8 +336,8 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
return contactName;
|
return contactName;
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveData<Boolean> hasImageSupport() {
|
LiveData<PrivateMessageFormat> getPrivateMessageFormat() {
|
||||||
return imageSupport;
|
return privateMessageFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveEvent<Boolean> showImageOnboarding() {
|
LiveEvent<Boolean> showImageOnboarding() {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public interface MessagingManager extends ConversationClient {
|
|||||||
/**
|
/**
|
||||||
* The current minor version of the messaging client.
|
* The current minor version of the messaging client.
|
||||||
*/
|
*/
|
||||||
int MINOR_VERSION = 2;
|
int MINOR_VERSION = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a local private message.
|
* Stores a local private message.
|
||||||
@@ -77,12 +77,8 @@ public interface MessagingManager extends ConversationClient {
|
|||||||
Attachment getAttachment(AttachmentHeader h) throws DbException;
|
Attachment getAttachment(AttachmentHeader h) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the contact with the given {@link ContactId} does support
|
* Returns the private message format supported by the given contact.
|
||||||
* image attachments.
|
|
||||||
*
|
|
||||||
* Added: 2019-01-01
|
|
||||||
*/
|
*/
|
||||||
boolean contactSupportsImages(Transaction txn, ContactId c)
|
PrivateMessageFormat getContactMessageFormat(Transaction txn, ContactId c)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,44 +8,66 @@ import java.util.List;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES_AUTO_DELETE;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class PrivateMessage {
|
public class PrivateMessage {
|
||||||
|
|
||||||
private final Message message;
|
private final Message message;
|
||||||
private final boolean legacyFormat, hasText;
|
private final boolean hasText;
|
||||||
private final List<AttachmentHeader> attachmentHeaders;
|
private final List<AttachmentHeader> attachmentHeaders;
|
||||||
|
private final long autoDeleteTimer;
|
||||||
|
private final PrivateMessageFormat format;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for private messages in the legacy format, which does not
|
* Constructor for private messages in the
|
||||||
* support attachments.
|
* {@link PrivateMessageFormat#TEXT_ONLY TEXT_ONLY} format.
|
||||||
*/
|
*/
|
||||||
public PrivateMessage(Message message) {
|
public PrivateMessage(Message message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
legacyFormat = true;
|
|
||||||
hasText = true;
|
hasText = true;
|
||||||
attachmentHeaders = emptyList();
|
attachmentHeaders = emptyList();
|
||||||
|
autoDeleteTimer = NO_AUTO_DELETE_TIMER;
|
||||||
|
format = TEXT_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for private messages in the current format, which supports
|
* Constructor for private messages in the
|
||||||
* attachments.
|
* {@link PrivateMessageFormat#TEXT_IMAGES TEXT_IMAGES} format.
|
||||||
*/
|
*/
|
||||||
public PrivateMessage(Message message, boolean hasText,
|
public PrivateMessage(Message message, boolean hasText,
|
||||||
List<AttachmentHeader> headers) {
|
List<AttachmentHeader> headers) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.hasText = hasText;
|
this.hasText = hasText;
|
||||||
this.attachmentHeaders = headers;
|
this.attachmentHeaders = headers;
|
||||||
legacyFormat = false;
|
autoDeleteTimer = NO_AUTO_DELETE_TIMER;
|
||||||
|
format = TEXT_IMAGES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for private messages in the
|
||||||
|
* {@link PrivateMessageFormat#TEXT_IMAGES_AUTO_DELETE TEXT_IMAGES_AUTO_DELETE}
|
||||||
|
* format.
|
||||||
|
*/
|
||||||
|
public PrivateMessage(Message message, boolean hasText,
|
||||||
|
List<AttachmentHeader> headers, long autoDeleteTimer) {
|
||||||
|
this.message = message;
|
||||||
|
this.hasText = hasText;
|
||||||
|
this.attachmentHeaders = headers;
|
||||||
|
this.autoDeleteTimer = autoDeleteTimer;
|
||||||
|
format = TEXT_IMAGES_AUTO_DELETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message getMessage() {
|
public Message getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLegacyFormat() {
|
public PrivateMessageFormat getFormat() {
|
||||||
return legacyFormat;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasText() {
|
public boolean hasText() {
|
||||||
@@ -55,4 +77,8 @@ public class PrivateMessage {
|
|||||||
public List<AttachmentHeader> getAttachmentHeaders() {
|
public List<AttachmentHeader> getAttachmentHeaders() {
|
||||||
return attachmentHeaders;
|
return attachmentHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getAutoDeleteTimer() {
|
||||||
|
return autoDeleteTimer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,29 @@ import javax.annotation.Nullable;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface PrivateMessageFactory {
|
public interface PrivateMessageFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a private message in the
|
||||||
|
* {@link PrivateMessageFormat#TEXT_ONLY TEXT_ONLY} format.
|
||||||
|
*/
|
||||||
PrivateMessage createLegacyPrivateMessage(GroupId groupId, long timestamp,
|
PrivateMessage createLegacyPrivateMessage(GroupId groupId, long timestamp,
|
||||||
String text) throws FormatException;
|
String text) throws FormatException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a private message in the
|
||||||
|
* {@link PrivateMessageFormat#TEXT_IMAGES TEXT_IMAGES} format. This format
|
||||||
|
* requires the contact to support client version 0.1 or higher.
|
||||||
|
*/
|
||||||
PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
|
PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
|
||||||
@Nullable String text, List<AttachmentHeader> headers)
|
@Nullable String text, List<AttachmentHeader> headers)
|
||||||
throws FormatException;
|
throws FormatException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a private message in the
|
||||||
|
* {@link PrivateMessageFormat#TEXT_IMAGES_AUTO_DELETE TEXT_IMAGES_AUTO_DELETE}
|
||||||
|
* format. This format requires the contact to support client version 0.3
|
||||||
|
* or higher.
|
||||||
|
*/
|
||||||
|
PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
|
||||||
|
@Nullable String text, List<AttachmentHeader> headers,
|
||||||
|
long autoDeleteTimer) throws FormatException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.briarproject.briar.api.messaging;
|
||||||
|
|
||||||
|
public enum PrivateMessageFormat {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First version of the private message format, which doesn't support
|
||||||
|
* image attachments or auto-deletion.
|
||||||
|
*/
|
||||||
|
TEXT_ONLY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Second version of the private message format, which supports image
|
||||||
|
* attachments but not auto-deletion. Support for this format was
|
||||||
|
* added in client version 0.1.
|
||||||
|
*/
|
||||||
|
TEXT_IMAGES,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Third version of the private message format, which supports image
|
||||||
|
* attachments and auto-deletion. Support for this format was added
|
||||||
|
* in client version 0.3.
|
||||||
|
*/
|
||||||
|
TEXT_IMAGES_AUTO_DELETE
|
||||||
|
}
|
||||||
@@ -16,13 +16,16 @@ public class PrivateMessageHeader extends ConversationMessageHeader {
|
|||||||
|
|
||||||
private final boolean hasText;
|
private final boolean hasText;
|
||||||
private final List<AttachmentHeader> attachmentHeaders;
|
private final List<AttachmentHeader> attachmentHeaders;
|
||||||
|
private final long autoDeleteTimer;
|
||||||
|
|
||||||
public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp,
|
public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp,
|
||||||
boolean local, boolean read, boolean sent, boolean seen,
|
boolean local, boolean read, boolean sent, boolean seen,
|
||||||
boolean hasText, List<AttachmentHeader> headers) {
|
boolean hasText, List<AttachmentHeader> headers,
|
||||||
|
long autoDeleteTimer) {
|
||||||
super(id, groupId, timestamp, local, read, sent, seen);
|
super(id, groupId, timestamp, local, read, sent, seen);
|
||||||
this.hasText = hasText;
|
this.hasText = hasText;
|
||||||
this.attachmentHeaders = headers;
|
this.attachmentHeaders = headers;
|
||||||
|
this.autoDeleteTimer = autoDeleteTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasText() {
|
public boolean hasText() {
|
||||||
@@ -33,9 +36,12 @@ public class PrivateMessageHeader extends ConversationMessageHeader {
|
|||||||
return attachmentHeaders;
|
return attachmentHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getAutoDeleteTimer() {
|
||||||
|
return autoDeleteTimer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T accept(ConversationMessageVisitor<T> v) {
|
public <T> T accept(ConversationMessageVisitor<T> v) {
|
||||||
return v.visitPrivateMessageHeader(this);
|
return v.visitPrivateMessageHeader(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ interface MessagingConstants {
|
|||||||
String MSG_KEY_DESCRIPTOR_LENGTH = "descriptorLength";
|
String MSG_KEY_DESCRIPTOR_LENGTH = "descriptorLength";
|
||||||
String MSG_KEY_HAS_TEXT = "hasText";
|
String MSG_KEY_HAS_TEXT = "hasText";
|
||||||
String MSG_KEY_ATTACHMENT_HEADERS = "attachmentHeaders";
|
String MSG_KEY_ATTACHMENT_HEADERS = "attachmentHeaders";
|
||||||
|
String MSG_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.briarproject.briar.api.messaging.FileTooBigException;
|
|||||||
import org.briarproject.briar.api.messaging.InvalidAttachmentException;
|
import org.briarproject.briar.api.messaging.InvalidAttachmentException;
|
||||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageFormat;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
||||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||||
@@ -57,14 +58,19 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES_AUTO_DELETE;
|
||||||
|
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY;
|
||||||
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
||||||
import static org.briarproject.briar.messaging.MessageTypes.ATTACHMENT;
|
import static org.briarproject.briar.messaging.MessageTypes.ATTACHMENT;
|
||||||
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.GROUP_KEY_CONTACT_ID;
|
import static org.briarproject.briar.messaging.MessagingConstants.GROUP_KEY_CONTACT_ID;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_ATTACHMENT_HEADERS;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_ATTACHMENT_HEADERS;
|
||||||
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_CONTENT_TYPE;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_CONTENT_TYPE;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_DESCRIPTOR_LENGTH;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_DESCRIPTOR_LENGTH;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_HAS_TEXT;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_HAS_TEXT;
|
||||||
@@ -196,9 +202,11 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
long timestamp = meta.getLong(MSG_KEY_TIMESTAMP);
|
long timestamp = meta.getLong(MSG_KEY_TIMESTAMP);
|
||||||
boolean local = meta.getBoolean(MSG_KEY_LOCAL);
|
boolean local = meta.getBoolean(MSG_KEY_LOCAL);
|
||||||
boolean read = meta.getBoolean(MSG_KEY_READ);
|
boolean read = meta.getBoolean(MSG_KEY_READ);
|
||||||
|
long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER,
|
||||||
|
NO_AUTO_DELETE_TIMER);
|
||||||
PrivateMessageHeader header =
|
PrivateMessageHeader header =
|
||||||
new PrivateMessageHeader(m.getId(), groupId, timestamp, local,
|
new PrivateMessageHeader(m.getId(), groupId, timestamp, local,
|
||||||
read, false, false, hasText, headers);
|
read, false, false, hasText, headers, timer);
|
||||||
ContactId contactId = getContactId(txn, groupId);
|
ContactId contactId = getContactId(txn, groupId);
|
||||||
PrivateMessageReceivedEvent event =
|
PrivateMessageReceivedEvent event =
|
||||||
new PrivateMessageReceivedEvent(header, contactId);
|
new PrivateMessageReceivedEvent(header, contactId);
|
||||||
@@ -234,7 +242,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
meta.put(MSG_KEY_TIMESTAMP, m.getMessage().getTimestamp());
|
meta.put(MSG_KEY_TIMESTAMP, m.getMessage().getTimestamp());
|
||||||
meta.put(MSG_KEY_LOCAL, true);
|
meta.put(MSG_KEY_LOCAL, true);
|
||||||
meta.put(MSG_KEY_READ, true);
|
meta.put(MSG_KEY_READ, true);
|
||||||
if (!m.isLegacyFormat()) {
|
if (m.getFormat() != TEXT_ONLY) {
|
||||||
meta.put(MSG_KEY_MSG_TYPE, PRIVATE_MESSAGE);
|
meta.put(MSG_KEY_MSG_TYPE, PRIVATE_MESSAGE);
|
||||||
meta.put(MSG_KEY_HAS_TEXT, m.hasText());
|
meta.put(MSG_KEY_HAS_TEXT, m.hasText());
|
||||||
BdfList headers = new BdfList();
|
BdfList headers = new BdfList();
|
||||||
@@ -243,6 +251,12 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
BdfList.of(a.getMessageId(), a.getContentType()));
|
BdfList.of(a.getMessageId(), a.getContentType()));
|
||||||
}
|
}
|
||||||
meta.put(MSG_KEY_ATTACHMENT_HEADERS, headers);
|
meta.put(MSG_KEY_ATTACHMENT_HEADERS, headers);
|
||||||
|
if (m.getFormat() == TEXT_IMAGES_AUTO_DELETE) {
|
||||||
|
long timer = m.getAutoDeleteTimer();
|
||||||
|
if (timer != NO_AUTO_DELETE_TIMER) {
|
||||||
|
meta.put(MSG_KEY_AUTO_DELETE_TIMER, timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Mark attachments as shared and permanent now we're ready to send
|
// Mark attachments as shared and permanent now we're ready to send
|
||||||
for (AttachmentHeader a : m.getAttachmentHeaders()) {
|
for (AttachmentHeader a : m.getAttachmentHeaders()) {
|
||||||
@@ -355,12 +369,14 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
if (messageType == null) {
|
if (messageType == null) {
|
||||||
headers.add(new PrivateMessageHeader(id, g, timestamp,
|
headers.add(new PrivateMessageHeader(id, g, timestamp,
|
||||||
local, read, s.isSent(), s.isSeen(), true,
|
local, read, s.isSent(), s.isSeen(), true,
|
||||||
emptyList()));
|
emptyList(), NO_AUTO_DELETE_TIMER));
|
||||||
} else {
|
} else {
|
||||||
boolean hasText = meta.getBoolean(MSG_KEY_HAS_TEXT);
|
boolean hasText = meta.getBoolean(MSG_KEY_HAS_TEXT);
|
||||||
|
long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER,
|
||||||
|
NO_AUTO_DELETE_TIMER);
|
||||||
headers.add(new PrivateMessageHeader(id, g, timestamp,
|
headers.add(new PrivateMessageHeader(id, g, timestamp,
|
||||||
local, read, s.isSent(), s.isSeen(), hasText,
|
local, read, s.isSent(), s.isSeen(), hasText,
|
||||||
parseAttachmentHeaders(meta)));
|
parseAttachmentHeaders(meta), timer));
|
||||||
}
|
}
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
@@ -422,12 +438,13 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contactSupportsImages(Transaction txn, ContactId c)
|
public PrivateMessageFormat getContactMessageFormat(Transaction txn,
|
||||||
throws DbException {
|
ContactId c) throws DbException {
|
||||||
int minorVersion = clientVersioningManager
|
int minorVersion = clientVersioningManager
|
||||||
.getClientMinorVersion(txn, c, CLIENT_ID, 0);
|
.getClientMinorVersion(txn, c, CLIENT_ID, 0);
|
||||||
// support was added in 0.1
|
if (minorVersion >= 3) return TEXT_IMAGES_AUTO_DELETE;
|
||||||
return minorVersion > 0;
|
else if (minorVersion >= 1) return TEXT_IMAGES;
|
||||||
|
else return TEXT_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import javax.annotation.Nullable;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.util.StringUtils.utf8IsTooLong;
|
import static org.briarproject.bramble.util.StringUtils.utf8IsTooLong;
|
||||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH;
|
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH;
|
||||||
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
||||||
@@ -47,21 +48,43 @@ class PrivateMessageFactoryImpl implements PrivateMessageFactory {
|
|||||||
public PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
|
public PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
|
||||||
@Nullable String text, List<AttachmentHeader> headers)
|
@Nullable String text, List<AttachmentHeader> headers)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
// Validate the arguments
|
validateTextAndAttachmentHeaders(text, headers);
|
||||||
if (text == null) {
|
BdfList attachmentList = serialiseAttachmentHeaders(headers);
|
||||||
if (headers.isEmpty()) throw new IllegalArgumentException();
|
|
||||||
} else if (utf8IsTooLong(text, MAX_PRIVATE_MESSAGE_TEXT_LENGTH)) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
// Serialise the attachment headers
|
|
||||||
BdfList attachmentList = new BdfList();
|
|
||||||
for (AttachmentHeader a : headers) {
|
|
||||||
attachmentList.add(
|
|
||||||
BdfList.of(a.getMessageId(), a.getContentType()));
|
|
||||||
}
|
|
||||||
// Serialise the message
|
// Serialise the message
|
||||||
BdfList body = BdfList.of(PRIVATE_MESSAGE, text, attachmentList);
|
BdfList body = BdfList.of(PRIVATE_MESSAGE, text, attachmentList);
|
||||||
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
||||||
return new PrivateMessage(m, text != null, headers);
|
return new PrivateMessage(m, text != null, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
|
||||||
|
@Nullable String text, List<AttachmentHeader> headers,
|
||||||
|
long autoDeleteTimer) throws FormatException {
|
||||||
|
validateTextAndAttachmentHeaders(text, headers);
|
||||||
|
BdfList attachmentList = serialiseAttachmentHeaders(headers);
|
||||||
|
// Serialise the message
|
||||||
|
Long timer = autoDeleteTimer == NO_AUTO_DELETE_TIMER ?
|
||||||
|
null : autoDeleteTimer;
|
||||||
|
BdfList body = BdfList.of(PRIVATE_MESSAGE, text, attachmentList, timer);
|
||||||
|
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
||||||
|
return new PrivateMessage(m, text != null, headers, autoDeleteTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTextAndAttachmentHeaders(@Nullable String text,
|
||||||
|
List<AttachmentHeader> headers) {
|
||||||
|
if (text == null) {
|
||||||
|
if (headers.isEmpty()) throw new IllegalArgumentException();
|
||||||
|
} else if (utf8IsTooLong(text, MAX_PRIVATE_MESSAGE_TEXT_LENGTH)) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BdfList serialiseAttachmentHeaders(List<AttachmentHeader> headers) {
|
||||||
|
BdfList attachmentList = new BdfList();
|
||||||
|
for (AttachmentHeader a : headers) {
|
||||||
|
attachmentList.add(
|
||||||
|
BdfList.of(a.getMessageId(), a.getContentType()));
|
||||||
|
}
|
||||||
|
return attachmentList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import java.io.InputStream;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||||
@@ -34,6 +36,7 @@ import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ
|
|||||||
import static org.briarproject.briar.messaging.MessageTypes.ATTACHMENT;
|
import static org.briarproject.briar.messaging.MessageTypes.ATTACHMENT;
|
||||||
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_ATTACHMENT_HEADERS;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_ATTACHMENT_HEADERS;
|
||||||
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_CONTENT_TYPE;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_CONTENT_TYPE;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_DESCRIPTOR_LENGTH;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_DESCRIPTOR_LENGTH;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_HAS_TEXT;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_HAS_TEXT;
|
||||||
@@ -99,7 +102,7 @@ class PrivateMessageValidator implements MessageValidator {
|
|||||||
|
|
||||||
private BdfMessageContext validateLegacyPrivateMessage(Message m,
|
private BdfMessageContext validateLegacyPrivateMessage(Message m,
|
||||||
BdfList body) throws FormatException {
|
BdfList body) throws FormatException {
|
||||||
// Private message text
|
// Client version 0.0: Private message text
|
||||||
checkSize(body, 1);
|
checkSize(body, 1);
|
||||||
String text = body.getString(0);
|
String text = body.getString(0);
|
||||||
checkLength(text, 0, MAX_PRIVATE_MESSAGE_TEXT_LENGTH);
|
checkLength(text, 0, MAX_PRIVATE_MESSAGE_TEXT_LENGTH);
|
||||||
@@ -113,8 +116,11 @@ class PrivateMessageValidator implements MessageValidator {
|
|||||||
|
|
||||||
private BdfMessageContext validatePrivateMessage(Message m, BdfList body)
|
private BdfMessageContext validatePrivateMessage(Message m, BdfList body)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
// Message type, optional private message text, attachment headers
|
// Client version 0.1 to 0.2: Message type, optional private message
|
||||||
checkSize(body, 3);
|
// text, attachment headers.
|
||||||
|
// Client version 0.3: Message type, optional private message text,
|
||||||
|
// attachment headers, optional auto-delete timer.
|
||||||
|
checkSize(body, 3, 4);
|
||||||
String text = body.getOptionalString(1);
|
String text = body.getOptionalString(1);
|
||||||
checkLength(text, 0, MAX_PRIVATE_MESSAGE_TEXT_LENGTH);
|
checkLength(text, 0, MAX_PRIVATE_MESSAGE_TEXT_LENGTH);
|
||||||
BdfList headers = body.getList(2);
|
BdfList headers = body.getList(2);
|
||||||
@@ -129,6 +135,12 @@ class PrivateMessageValidator implements MessageValidator {
|
|||||||
String contentType = header.getString(1);
|
String contentType = header.getString(1);
|
||||||
checkLength(contentType, 1, MAX_CONTENT_TYPE_BYTES);
|
checkLength(contentType, 1, MAX_CONTENT_TYPE_BYTES);
|
||||||
}
|
}
|
||||||
|
Long timer = null;
|
||||||
|
if (body.size() == 4) timer = body.getOptionalLong(3);
|
||||||
|
if (timer != null && (timer < MIN_AUTO_DELETE_TIMER_MS ||
|
||||||
|
timer > MAX_AUTO_DELETE_TIMER_MS)) {
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
// Return the metadata
|
// Return the metadata
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
meta.put(MSG_KEY_TIMESTAMP, m.getTimestamp());
|
meta.put(MSG_KEY_TIMESTAMP, m.getTimestamp());
|
||||||
@@ -137,6 +149,7 @@ class PrivateMessageValidator implements MessageValidator {
|
|||||||
meta.put(MSG_KEY_MSG_TYPE, PRIVATE_MESSAGE);
|
meta.put(MSG_KEY_MSG_TYPE, PRIVATE_MESSAGE);
|
||||||
meta.put(MSG_KEY_HAS_TEXT, text != null);
|
meta.put(MSG_KEY_HAS_TEXT, text != null);
|
||||||
meta.put(MSG_KEY_ATTACHMENT_HEADERS, headers);
|
meta.put(MSG_KEY_ATTACHMENT_HEADERS, headers);
|
||||||
|
if (timer != null) meta.put(MSG_KEY_AUTO_DELETE_TIMER, timer);
|
||||||
return new BdfMessageContext(meta);
|
return new BdfMessageContext(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ import javax.inject.Inject;
|
|||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
@@ -316,13 +318,17 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
long timestamp = clock.currentTimeMillis() - num * 60 * 1000;
|
long timestamp = clock.currentTimeMillis() - num * 60 * 1000;
|
||||||
String text = getRandomText();
|
String text = getRandomText();
|
||||||
boolean local = random.nextBoolean();
|
boolean local = random.nextBoolean();
|
||||||
createPrivateMessage(groupId, text, timestamp, local);
|
boolean autoDelete = random.nextBoolean();
|
||||||
|
createPrivateMessage(groupId, text, timestamp, local, autoDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPrivateMessage(GroupId groupId, String text,
|
private void createPrivateMessage(GroupId groupId, String text,
|
||||||
long timestamp, boolean local) throws DbException, FormatException {
|
long timestamp, boolean local, boolean autoDelete)
|
||||||
PrivateMessage m = privateMessageFactory
|
throws DbException, FormatException {
|
||||||
.createPrivateMessage(groupId, timestamp, text, emptyList());
|
long timer = autoDelete ?
|
||||||
|
MIN_AUTO_DELETE_TIMER_MS : NO_AUTO_DELETE_TIMER;
|
||||||
|
PrivateMessage m = privateMessageFactory.createPrivateMessage(groupId,
|
||||||
|
timestamp, text, emptyList(), timer);
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
meta.put("timestamp", timestamp);
|
meta.put("timestamp", timestamp);
|
||||||
meta.put("local", local);
|
meta.put("local", local);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
||||||
@@ -77,12 +78,12 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
getRandomString(MAX_CONTENT_TYPE_BYTES)));
|
getRandomString(MAX_CONTENT_TYPE_BYTES)));
|
||||||
}
|
}
|
||||||
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
||||||
groupId, timestamp, text, headers);
|
groupId, timestamp, text, headers, MAX_AUTO_DELETE_TIMER_MS);
|
||||||
// Check the size of the serialised message
|
// Check the size of the serialised message
|
||||||
int length = message.getMessage().getRawLength();
|
int length = message.getMessage().getRawLength();
|
||||||
assertTrue(length > UniqueId.LENGTH + 8
|
assertTrue(length > UniqueId.LENGTH + 8
|
||||||
+ MAX_PRIVATE_MESSAGE_TEXT_LENGTH + MAX_ATTACHMENTS_PER_MESSAGE
|
+ MAX_PRIVATE_MESSAGE_TEXT_LENGTH + MAX_ATTACHMENTS_PER_MESSAGE
|
||||||
* (UniqueId.LENGTH + MAX_CONTENT_TYPE_BYTES));
|
* (UniqueId.LENGTH + MAX_CONTENT_TYPE_BYTES) + 4);
|
||||||
assertTrue(length <= MAX_RECORD_PAYLOAD_BYTES);
|
assertTrue(length <= MAX_RECORD_PAYLOAD_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import static java.util.Collections.emptyList;
|
|||||||
import static java.util.Collections.emptySet;
|
import static java.util.Collections.emptySet;
|
||||||
import static java.util.Collections.singleton;
|
import static java.util.Collections.singleton;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
@@ -89,7 +91,7 @@ public class MessagingManagerIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleConversation() throws Exception {
|
public void testSimpleConversation() throws Exception {
|
||||||
// conversation start out empty
|
// conversation starts out empty
|
||||||
Collection<ConversationMessageHeader> messages0 = getMessages(c0);
|
Collection<ConversationMessageHeader> messages0 = getMessages(c0);
|
||||||
Collection<ConversationMessageHeader> messages1 = getMessages(c1);
|
Collection<ConversationMessageHeader> messages1 = getMessages(c1);
|
||||||
assertEquals(0, messages0.size());
|
assertEquals(0, messages0.size());
|
||||||
@@ -108,6 +110,10 @@ public class MessagingManagerIntegrationTest
|
|||||||
(PrivateMessageHeader) messages1.iterator().next();
|
(PrivateMessageHeader) messages1.iterator().next();
|
||||||
assertTrue(m0.hasText());
|
assertTrue(m0.hasText());
|
||||||
assertTrue(m1.hasText());
|
assertTrue(m1.hasText());
|
||||||
|
assertEquals(0, m0.getAttachmentHeaders().size());
|
||||||
|
assertEquals(0, m1.getAttachmentHeaders().size());
|
||||||
|
assertEquals(NO_AUTO_DELETE_TIMER, m0.getAutoDeleteTimer());
|
||||||
|
assertEquals(NO_AUTO_DELETE_TIMER, m1.getAutoDeleteTimer());
|
||||||
assertTrue(m0.isRead());
|
assertTrue(m0.isRead());
|
||||||
assertFalse(m1.isRead());
|
assertFalse(m1.isRead());
|
||||||
assertGroupCounts(c0, 1, 0);
|
assertGroupCounts(c0, 1, 0);
|
||||||
@@ -143,13 +149,44 @@ public class MessagingManagerIntegrationTest
|
|||||||
assertFalse(m1.hasText());
|
assertFalse(m1.hasText());
|
||||||
assertEquals(1, m0.getAttachmentHeaders().size());
|
assertEquals(1, m0.getAttachmentHeaders().size());
|
||||||
assertEquals(1, m1.getAttachmentHeaders().size());
|
assertEquals(1, m1.getAttachmentHeaders().size());
|
||||||
|
assertEquals(NO_AUTO_DELETE_TIMER, m0.getAutoDeleteTimer());
|
||||||
|
assertEquals(NO_AUTO_DELETE_TIMER, m1.getAutoDeleteTimer());
|
||||||
|
assertTrue(m0.isRead());
|
||||||
|
assertFalse(m1.isRead());
|
||||||
|
assertGroupCounts(c0, 1, 0);
|
||||||
|
assertGroupCounts(c1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAutoDeleteTimer() throws Exception {
|
||||||
|
// send message with auto-delete timer
|
||||||
|
sendMessage(c0, c1, getRandomString(123), emptyList(),
|
||||||
|
MIN_AUTO_DELETE_TIMER_MS);
|
||||||
|
|
||||||
|
// message with timer is sent/displayed properly
|
||||||
|
Collection<ConversationMessageHeader> messages0 = getMessages(c0);
|
||||||
|
Collection<ConversationMessageHeader> messages1 = getMessages(c1);
|
||||||
|
assertEquals(1, messages0.size());
|
||||||
|
assertEquals(1, messages1.size());
|
||||||
|
PrivateMessageHeader m0 =
|
||||||
|
(PrivateMessageHeader) messages0.iterator().next();
|
||||||
|
PrivateMessageHeader m1 =
|
||||||
|
(PrivateMessageHeader) messages1.iterator().next();
|
||||||
|
assertTrue(m0.hasText());
|
||||||
|
assertTrue(m1.hasText());
|
||||||
|
assertEquals(0, m0.getAttachmentHeaders().size());
|
||||||
|
assertEquals(0, m1.getAttachmentHeaders().size());
|
||||||
|
assertEquals(MIN_AUTO_DELETE_TIMER_MS, m0.getAutoDeleteTimer());
|
||||||
|
assertEquals(MIN_AUTO_DELETE_TIMER_MS, m1.getAutoDeleteTimer());
|
||||||
|
assertTrue(m0.isRead());
|
||||||
|
assertFalse(m1.isRead());
|
||||||
assertGroupCounts(c0, 1, 0);
|
assertGroupCounts(c0, 1, 0);
|
||||||
assertGroupCounts(c1, 1, 1);
|
assertGroupCounts(c1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteAll() throws Exception {
|
public void testDeleteAll() throws Exception {
|
||||||
// send 3 message (1 with attachment)
|
// send 3 messages (1 with attachment)
|
||||||
sendMessage(c0, c1, getRandomString(42));
|
sendMessage(c0, c1, getRandomString(42));
|
||||||
sendMessage(c0, c1, getRandomString(23));
|
sendMessage(c0, c1, getRandomString(23));
|
||||||
sendMessage(c0, c1, null, singletonList(addAttachment(c0)));
|
sendMessage(c0, c1, null, singletonList(addAttachment(c0)));
|
||||||
@@ -331,17 +368,23 @@ public class MessagingManagerIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
private PrivateMessage sendMessage(BriarIntegrationTestComponent from,
|
private PrivateMessage sendMessage(BriarIntegrationTestComponent from,
|
||||||
BriarIntegrationTestComponent to, String text)
|
BriarIntegrationTestComponent to, String text) throws Exception {
|
||||||
throws Exception {
|
|
||||||
return sendMessage(from, to, text, emptyList());
|
return sendMessage(from, to, text, emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private PrivateMessage sendMessage(BriarIntegrationTestComponent from,
|
private PrivateMessage sendMessage(BriarIntegrationTestComponent from,
|
||||||
BriarIntegrationTestComponent to, @Nullable String text,
|
BriarIntegrationTestComponent to, @Nullable String text,
|
||||||
List<AttachmentHeader> attachments) throws Exception {
|
List<AttachmentHeader> attachments) throws Exception {
|
||||||
|
return sendMessage(from, to, text, attachments, NO_AUTO_DELETE_TIMER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PrivateMessage sendMessage(BriarIntegrationTestComponent from,
|
||||||
|
BriarIntegrationTestComponent to, @Nullable String text,
|
||||||
|
List<AttachmentHeader> attachments, long autoDeleteTimer)
|
||||||
|
throws Exception {
|
||||||
GroupId g = from.getMessagingManager().getConversationId(contactId);
|
GroupId g = from.getMessagingManager().getConversationId(contactId);
|
||||||
PrivateMessage m = messageFactory.createPrivateMessage(g,
|
PrivateMessage m = messageFactory.createPrivateMessage(g,
|
||||||
clock.currentTimeMillis(), text, attachments);
|
clock.currentTimeMillis(), text, attachments, autoDeleteTimer);
|
||||||
from.getMessagingManager().addLocalMessage(m);
|
from.getMessagingManager().addLocalMessage(m);
|
||||||
syncMessage(from, to, contactId, 1 + attachments.size(), true);
|
syncMessage(from, to, contactId, 1 + attachments.size(), true);
|
||||||
return m;
|
return m;
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||||
@@ -34,6 +36,7 @@ import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ
|
|||||||
import static org.briarproject.briar.messaging.MessageTypes.ATTACHMENT;
|
import static org.briarproject.briar.messaging.MessageTypes.ATTACHMENT;
|
||||||
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
import static org.briarproject.briar.messaging.MessageTypes.PRIVATE_MESSAGE;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_ATTACHMENT_HEADERS;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_ATTACHMENT_HEADERS;
|
||||||
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_CONTENT_TYPE;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_CONTENT_TYPE;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_DESCRIPTOR_LENGTH;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_DESCRIPTOR_LENGTH;
|
||||||
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_HAS_TEXT;
|
import static org.briarproject.briar.messaging.MessagingConstants.MSG_KEY_HAS_TEXT;
|
||||||
@@ -391,6 +394,48 @@ public class PrivateMessageValidatorTest extends BrambleMockTestCase {
|
|||||||
validator.validateMessage(message, group);
|
validator.validateMessage(message, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsNullTimerForPrivateMessage() throws Exception {
|
||||||
|
testAcceptsPrivateMessage(BdfList.of(PRIVATE_MESSAGE, text,
|
||||||
|
new BdfList(), null), noAttachmentsMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidMessageException.class)
|
||||||
|
public void testRejectsNonLongTimerForPrivateMessage() throws Exception {
|
||||||
|
testRejectsPrivateMessage(BdfList.of(PRIVATE_MESSAGE, text,
|
||||||
|
new BdfList(), "foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidMessageException.class)
|
||||||
|
public void testRejectsTooSmallTimerForPrivateMessage() throws Exception {
|
||||||
|
testRejectsPrivateMessage(BdfList.of(PRIVATE_MESSAGE, text,
|
||||||
|
new BdfList(), MIN_AUTO_DELETE_TIMER_MS - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidMessageException.class)
|
||||||
|
public void testRejectsTooBigTimerForPrivateMessage() throws Exception {
|
||||||
|
testRejectsPrivateMessage(BdfList.of(PRIVATE_MESSAGE, text,
|
||||||
|
new BdfList(), MAX_AUTO_DELETE_TIMER_MS + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsMinTimerForPrivateMessage() throws Exception {
|
||||||
|
BdfDictionary minTimerMeta = new BdfDictionary(noAttachmentsMeta);
|
||||||
|
minTimerMeta.put(MSG_KEY_AUTO_DELETE_TIMER, MIN_AUTO_DELETE_TIMER_MS);
|
||||||
|
|
||||||
|
testAcceptsPrivateMessage(BdfList.of(PRIVATE_MESSAGE, text,
|
||||||
|
new BdfList(), MIN_AUTO_DELETE_TIMER_MS), minTimerMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsMaxTimerForPrivateMessage() throws Exception {
|
||||||
|
BdfDictionary maxTimerMeta = new BdfDictionary(noAttachmentsMeta);
|
||||||
|
maxTimerMeta.put(MSG_KEY_AUTO_DELETE_TIMER, MAX_AUTO_DELETE_TIMER_MS);
|
||||||
|
|
||||||
|
testAcceptsPrivateMessage(BdfList.of(PRIVATE_MESSAGE, text,
|
||||||
|
new BdfList(), MAX_AUTO_DELETE_TIMER_MS), maxTimerMeta);
|
||||||
|
}
|
||||||
|
|
||||||
private void testRejectsLegacyMessage(BdfList body) throws Exception {
|
private void testRejectsLegacyMessage(BdfList body) throws Exception {
|
||||||
expectCheckTimestamp(now);
|
expectCheckTimestamp(now);
|
||||||
expectParseList(body);
|
expectParseList(body);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import java.util.concurrent.CountDownLatch;
|
|||||||
|
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||||
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.test.TestPluginConfigModule.SIMPLEX_TRANSPORT_ID;
|
import static org.briarproject.bramble.test.TestPluginConfigModule.SIMPLEX_TRANSPORT_ID;
|
||||||
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
@@ -123,7 +124,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
PrivateMessageFactory privateMessageFactory =
|
PrivateMessageFactory privateMessageFactory =
|
||||||
device.getPrivateMessageFactory();
|
device.getPrivateMessageFactory();
|
||||||
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
||||||
groupId, timestamp, "Hi!", singletonList(attachmentHeader));
|
groupId, timestamp, "Hi!", singletonList(attachmentHeader),
|
||||||
|
NO_AUTO_DELETE_TIMER);
|
||||||
messagingManager.addLocalMessage(message);
|
messagingManager.addLocalMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.mockk.CapturingSlot
|
|||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
|
import org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER
|
||||||
import org.briarproject.bramble.api.identity.AuthorInfo
|
import org.briarproject.bramble.api.identity.AuthorInfo
|
||||||
import org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED
|
import org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED
|
||||||
import org.briarproject.bramble.test.ImmediateExecutor
|
import org.briarproject.bramble.test.ImmediateExecutor
|
||||||
@@ -41,7 +42,8 @@ internal class WebSocketControllerTest : ControllerTest() {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
emptyList()
|
emptyList(),
|
||||||
|
NO_AUTO_DELETE_TIMER
|
||||||
)
|
)
|
||||||
private val event = PrivateMessageReceivedEvent(header, contact.id)
|
private val event = PrivateMessageReceivedEvent(header, contact.id)
|
||||||
private val outputEvent = OutputEvent(EVENT_CONVERSATION_MESSAGE, event.output(text))
|
private val outputEvent = OutputEvent(EVENT_CONVERSATION_MESSAGE, event.output(text))
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ import io.javalin.http.BadRequestResponse
|
|||||||
import io.javalin.http.Context
|
import io.javalin.http.Context
|
||||||
import io.javalin.http.NotFoundResponse
|
import io.javalin.http.NotFoundResponse
|
||||||
import io.javalin.plugin.json.JavalinJson.toJson
|
import io.javalin.plugin.json.JavalinJson.toJson
|
||||||
import io.mockk.*
|
import io.mockk.CapturingSlot
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.just
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.runs
|
||||||
|
import org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER
|
||||||
import org.briarproject.bramble.api.contact.ContactId
|
import org.briarproject.bramble.api.contact.ContactId
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException
|
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||||
import org.briarproject.bramble.api.identity.AuthorInfo
|
import org.briarproject.bramble.api.identity.AuthorInfo
|
||||||
@@ -62,7 +69,8 @@ internal class MessagingControllerImplTest : ControllerTest() {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
emptyList()
|
emptyList(),
|
||||||
|
NO_AUTO_DELETE_TIMER
|
||||||
)
|
)
|
||||||
private val sessionId = SessionId(getRandomId())
|
private val sessionId = SessionId(getRandomId())
|
||||||
private val privateMessage = PrivateMessage(message)
|
private val privateMessage = PrivateMessage(message)
|
||||||
|
|||||||
Reference in New Issue
Block a user