Support for Contact Discovery Service

This commit is contained in:
Ken Powers 2020-09-03 21:25:19 -04:00 committed by Scott Nonnenberg
parent f6dcf91dbf
commit 8290881bd8
21 changed files with 961 additions and 79 deletions

View file

@ -184,6 +184,39 @@
);
},
isEverUnregistered() {
return Boolean(this.get('discoveredUnregisteredAt'));
},
isUnregistered() {
const now = Date.now();
const sixHoursAgo = now - 1000 * 60 * 60 * 6;
const discoveredUnregisteredAt = this.get('discoveredUnregisteredAt');
if (discoveredUnregisteredAt && discoveredUnregisteredAt > sixHoursAgo) {
return true;
}
return false;
},
setUnregistered() {
window.log.info(
`Conversation ${this.idForLogging()} is now unregistered`
);
this.set({
discoveredUnregisteredAt: Date.now(),
});
window.Signal.Data.updateConversation(this.attributes);
},
setRegistered() {
window.log.info(
`Conversation ${this.idForLogging()} is registered once again`
);
this.set({
discoveredUnregisteredAt: undefined,
});
window.Signal.Data.updateConversation(this.attributes);
},
isBlocked() {
const uuid = this.get('uuid');
if (uuid) {
@ -1258,6 +1291,11 @@
if (c.id === me) {
return null;
}
// We don't want to even attempt a send if we have recently discovered that they
// are unregistered.
if (c.isUnregistered()) {
return null;
}
return c.getSendTarget();
})
);
@ -1422,7 +1460,7 @@
});
Whisper.Reactions.onReaction(reactionModel);
const destination = this.get('e164');
const destination = this.getSendTarget();
const recipients = this.getRecipients();
let profileKey;
@ -1717,7 +1755,8 @@
if (result) {
await this.handleMessageSendResult(
result.failoverIdentifiers,
result.unidentifiedDeliveries
result.unidentifiedDeliveries,
result.discoveredIdentifierPairs
);
}
return result;
@ -1727,7 +1766,8 @@
if (result) {
await this.handleMessageSendResult(
result.failoverIdentifiers,
result.unidentifiedDeliveries
result.unidentifiedDeliveries,
result.discoveredIdentifierPairs
);
}
throw result;
@ -1735,7 +1775,20 @@
);
},
async handleMessageSendResult(failoverIdentifiers, unidentifiedDeliveries) {
async handleMessageSendResult(
failoverIdentifiers,
unidentifiedDeliveries,
discoveredIdentifierPairs
) {
discoveredIdentifierPairs.forEach(item => {
const { uuid, e164 } = item;
window.ConversationController.ensureContactIds({
uuid,
e164,
highTrust: true,
});
});
await Promise.all(
(failoverIdentifiers || []).map(async identifier => {
const conversation = ConversationController.get(identifier);

View file

@ -1716,6 +1716,14 @@
let promises = [];
// If we successfully sent to a user, we can remove our unregistered flag.
result.successfulIdentifiers.forEach(identifier => {
const c = ConversationController.get(identifier);
if (c && c.isEverUnregistered()) {
c.setRegistered();
}
});
if (result instanceof Error) {
this.saveErrors(result);
if (result.name === 'SignedPreKeyRotationError') {
@ -1728,6 +1736,24 @@
if (result.successfulIdentifiers.length > 0) {
const sentTo = this.get('sent_to') || [];
// If we just found out that we couldn't send to a user because they are no
// longer registered, we will update our unregistered flag. In groups we
// will not event try to send to them for 6 hours. And we will never try
// to fetch them on startup again.
// The way to discover registration once more is:
// 1) any attempt to send to them in 1:1 conversation
// 2) the six-hour time period has passed and we send in a group again
const unregisteredUserErrors = _.filter(
result.errors,
error => error.name === 'UnregisteredUserError'
);
unregisteredUserErrors.forEach(error => {
const c = ConversationController.get(error.identifier);
if (c) {
c.setUnregistered();
}
});
// In groups, we don't treat unregistered users as a user-visible
// error. The message will look successful, but the details
// screen will show that we didn't send to these unregistered users.