) {
final var messageSendLogStore = account.getMessageSendLogStore();
final var result = handleSendMessage(recipientId,
- (messageSender, address, unidentifiedAccess) -> messageSender.sendReceipt(address,
+ (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendReceipt(address,
unidentifiedAccess,
receiptMessage,
- false));
+ includePniSignature));
messageSendLogStore.insertIfPossible(receiptMessage.getWhen(), result, ContentHint.IMPLICIT, false);
handleSendMessageResult(result);
return result;
.withProfileKey(profileKey)
.build();
return handleSendMessage(recipientId,
- (messageSender, address, unidentifiedAccess) -> messageSender.sendDataMessage(address,
+ (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendDataMessage(
+ address,
unidentifiedAccess,
ContentHint.IMPLICIT,
message,
SignalServiceMessageSender.IndividualSendEvents.EMPTY,
false,
- false));
+ includePniSignature));
}
public SendMessageResult sendRetryReceipt(
recipientId,
errorMessage.getDeviceId());
final var result = handleSendMessage(recipientId,
- (messageSender, address, unidentifiedAccess) -> messageSender.sendRetryReceipt(address,
+ (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendRetryReceipt(
+ address,
unidentifiedAccess,
groupId.map(GroupId::serialize),
errorMessage));
}
public SendMessageResult sendNullMessage(RecipientId recipientId) {
- final var result = handleSendMessage(recipientId, SignalServiceMessageSender::sendNullMessage);
+ final var result = handleSendMessage(recipientId,
+ (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendNullMessage(
+ address,
+ unidentifiedAccess));
handleSendMessageResult(result);
return result;
}
SignalServiceTypingMessage message, RecipientId recipientId
) {
final var result = handleSendMessage(recipientId,
- (messageSender, address, unidentifiedAccess) -> messageSender.sendTyping(List.of(address),
- List.of(unidentifiedAccess),
- message,
- null).getFirst());
+ (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendTyping(List.of(
+ address), List.of(unidentifiedAccess), message, null).getFirst());
handleSendMessageResult(result);
return result;
}
logger.trace("Resending message {} to {}", timestamp, recipientId);
if (messageSendLogEntry.groupId().isEmpty()) {
return handleSendMessage(recipientId,
- (messageSender, address, unidentifiedAccess) -> messageSender.resendContent(address,
+ (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.resendContent(
+ address,
unidentifiedAccess,
timestamp,
messageSendLogEntry.content(),
.build();
final var result = handleSendMessage(recipientId,
- (messageSender, address, unidentifiedAccess) -> messageSender.resendContent(address,
+ (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.resendContent(address,
unidentifiedAccess,
timestamp,
contentToSend,
) {
final var messageSendLogStore = account.getMessageSendLogStore();
final var urgent = true;
- final var includePniSignature = false;
final var result = handleSendMessage(recipientId,
editTargetTimestamp.isEmpty()
- ? (messageSender, address, unidentifiedAccess) -> messageSender.sendDataMessage(address,
+ ? (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendDataMessage(
+ address,
unidentifiedAccess,
ContentHint.RESENDABLE,
message,
SignalServiceMessageSender.IndividualSendEvents.EMPTY,
urgent,
includePniSignature)
- : (messageSender, address, unidentifiedAccess) -> messageSender.sendEditMessage(address,
+ : (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendEditMessage(
+ address,
unidentifiedAccess,
ContentHint.RESENDABLE,
message,
var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
try {
+ final boolean includePniSignature = account.getRecipientStore().needsPniSignature(recipientId);
try {
- return s.send(messageSender, address, context.getUnidentifiedAccessHelper().getAccessFor(recipientId));
+ return s.send(messageSender,
+ address,
+ context.getUnidentifiedAccessHelper().getAccessFor(recipientId),
+ includePniSignature);
} catch (UnregisteredUserException e) {
final RecipientId newRecipientId;
try {
address = context.getRecipientHelper().resolveSignalServiceAddress(newRecipientId);
return s.send(messageSender,
address,
- context.getUnidentifiedAccessHelper().getAccessFor(newRecipientId));
+ context.getUnidentifiedAccessHelper().getAccessFor(newRecipientId),
+ includePniSignature);
}
} catch (UnregisteredUserException e) {
return SendMessageResult.unregisteredFailure(address);
SendMessageResult send(
SignalServiceMessageSender messageSender,
SignalServiceAddress address,
- Optional<UnidentifiedAccessPair> unidentifiedAccess
+ Optional<UnidentifiedAccessPair> unidentifiedAccess,
+ boolean includePniSignature
) throws IOException, UnregisteredUserException, ProofRequiredException, RateLimitException, org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
}
unregistered_timestamp INTEGER,
profile_key BLOB,
profile_key_credential BLOB,
+ needs_pni_signature INTEGER NOT NULL DEFAULT FALSE,
given_name TEXT,
family_name TEXT,
return count;
}
+ public void markNeedsPniSignature(final RecipientId recipientId, final boolean value) {
+ logger.debug("Marking {} numbers as need pni signature = {}", recipientId, value);
+ try (final var connection = database.getConnection()) {
+ final var sql = (
+ """
+ UPDATE %s
+ SET needs_pni_signature = ?
+ WHERE _id = ?
+ """
+ ).formatted(TABLE_RECIPIENT);
+ try (final var statement = connection.prepareStatement(sql)) {
+ statement.setBoolean(1, value);
+ statement.setLong(2, recipientId.id());
+ statement.executeUpdate();
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException("Failed update recipient store", e);
+ }
+ }
+
+ public boolean needsPniSignature(final RecipientId recipientId) {
+ try (final var connection = database.getConnection()) {
+ final var sql = (
+ """
+ SELECT needs_pni_signature
+ FROM %s
+ WHERE _id = ?
+ """
+ ).formatted(TABLE_RECIPIENT);
+ try (final var statement = connection.prepareStatement(sql)) {
+ statement.setLong(1, recipientId.id());
+ return Utils.executeQuerySingleRow(statement, resultSet -> resultSet.getBoolean("needs_pni_signature"));
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException("Failed read recipient store", e);
+ }
+ }
+
public void markUnregistered(final Set<String> unregisteredUsers) {
logger.debug("Marking {} numbers as unregistered", unregisteredUsers.size());
try (final var connection = database.getConnection()) {