Fix GSE for delivery receipts in inactive groups
Co-authored-by: Jamie Kyle <113370520+jamiebuilds-signal@users.noreply.github.com>
This commit is contained in:
parent
08e8a7c6e9
commit
80367143cc
3 changed files with 33 additions and 36 deletions
|
@ -458,7 +458,9 @@ async function doGetProfile(
|
|||
c: ConversationModel,
|
||||
groupId: string | null
|
||||
): Promise<void> {
|
||||
const logId = `getProfile(${c.idForLogging()})`;
|
||||
const logId = groupId
|
||||
? `getProfile(${c.idForLogging()} in groupv2(${groupId}))`
|
||||
: `getProfile(${c.idForLogging()})`;
|
||||
const { messaging } = window.textsecure;
|
||||
strictAssert(
|
||||
messaging,
|
||||
|
|
|
@ -30,7 +30,7 @@ import { isTestOrMockEnvironment } from '../environment';
|
|||
import { isAlpha } from './version';
|
||||
import { parseStrict } from './schemas';
|
||||
import { DataReader } from '../sql/Client';
|
||||
import { maybeUpdateGroup } from '../groups';
|
||||
import { waitThenMaybeUpdateGroup } from '../groups';
|
||||
import { isGroupV2 } from './whatTypeOfConversation';
|
||||
|
||||
export function decodeGroupSendEndorsementResponse({
|
||||
|
@ -139,6 +139,7 @@ export function isValidGroupSendEndorsementsExpiration(
|
|||
}
|
||||
|
||||
export class GroupSendEndorsementState {
|
||||
#logId: string;
|
||||
#combinedEndorsement: GroupSendCombinedEndorsementRecord;
|
||||
#memberEndorsements = new Map<
|
||||
ServiceIdString,
|
||||
|
@ -153,6 +154,7 @@ export class GroupSendEndorsementState {
|
|||
data: GroupSendEndorsementsData,
|
||||
groupSecretParamsBase64: string
|
||||
) {
|
||||
this.#logId = `GroupSendEndorsementState/groupv2(${data.combinedEndorsement.groupId})`;
|
||||
this.#combinedEndorsement = data.combinedEndorsement;
|
||||
this.#groupSecretParamsBase64 = groupSecretParamsBase64;
|
||||
this.#ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
@ -194,7 +196,7 @@ export class GroupSendEndorsementState {
|
|||
|
||||
strictAssert(
|
||||
isValidGroupSendEndorsementsExpiration(expiration.getTime()),
|
||||
'Cannot build token with invalid expiration'
|
||||
`${this.#logId}: toToken: Cannot build token with invalid expiration`
|
||||
);
|
||||
|
||||
const fullToken = endorsement.toFullToken(groupSecretParams, expiration);
|
||||
|
@ -218,7 +220,7 @@ export class GroupSendEndorsementState {
|
|||
const memberEndorsement = this.#memberEndorsements.get(serviceId);
|
||||
strictAssert(
|
||||
memberEndorsement,
|
||||
'subtractMemberEndorsements: Missing endorsement'
|
||||
`${this.#logId}: getMemberEndorsement: Missing endorsement for ${serviceId}`
|
||||
);
|
||||
return this.#toEndorsement(memberEndorsement.endorsement);
|
||||
}
|
||||
|
@ -231,7 +233,7 @@ export class GroupSendEndorsementState {
|
|||
): GroupSendEndorsement {
|
||||
strictAssert(
|
||||
!otherMembersServiceIds.has(this.#ourAci),
|
||||
'subtractMemberEndorsements: Cannot subtract our own aci from the combined endorsement'
|
||||
`${this.#logId}: subtractMemberEndorsements: Cannot subtract our own aci from the combined endorsement`
|
||||
);
|
||||
return this.#getCombinedEndorsement(includesOurs).byRemoving(
|
||||
this.#combineMemberEndorsements(otherMembersServiceIds)
|
||||
|
@ -253,7 +255,7 @@ export class GroupSendEndorsementState {
|
|||
#buildToken(serviceIds: Set<ServiceIdString>): GroupSendEndorsement {
|
||||
const sendCount = serviceIds.size;
|
||||
const memberCount = this.#memberEndorsements.size;
|
||||
const logId = `GroupSendEndorsementState.buildToken(${sendCount} of ${memberCount})`;
|
||||
const logId = `${this.#logId}: buildToken(${sendCount} of ${memberCount})`;
|
||||
|
||||
// Fast path sending to one person
|
||||
if (serviceIds.size === 1) {
|
||||
|
@ -351,6 +353,12 @@ export async function maybeCreateGroupSendEndorsementState(
|
|||
if (data == null) {
|
||||
const ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||
if (conversation.isMember(ourAci)) {
|
||||
if (!alreadyRefreshedGroupState) {
|
||||
log.info(`${logId}: Missing endorsements for group, refreshing group`);
|
||||
await waitThenMaybeUpdateGroup({ conversation, force: true });
|
||||
return { state: null, didRefreshGroupState: true };
|
||||
}
|
||||
|
||||
onFailedToSendWithEndorsements(
|
||||
new Error(`${logId}: Missing all endorsements for group`)
|
||||
);
|
||||
|
@ -374,7 +382,7 @@ export async function maybeCreateGroupSendEndorsementState(
|
|||
log.info(
|
||||
`${logId}: Endorsements close to expiration (${groupSendEndorsementState.getExpiration().getTime()}, ${Date.now()}), refreshing group`
|
||||
);
|
||||
await maybeUpdateGroup({ conversation });
|
||||
await waitThenMaybeUpdateGroup({ conversation, force: true });
|
||||
return { state: null, didRefreshGroupState: true };
|
||||
}
|
||||
|
||||
|
|
|
@ -296,22 +296,20 @@ export async function sendToGroupViaSenderKey(
|
|||
} = options;
|
||||
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
|
||||
|
||||
const logId = sendTarget.idForLogging();
|
||||
const logId = `sendToGroupViaSenderKey/${sendTarget.idForLogging()}`;
|
||||
log.info(
|
||||
`sendToGroupViaSenderKey/${logId}: Starting ${timestamp}, recursion count ${recursion.count}, reason: ${recursion.reason}...`
|
||||
`${logId}: Starting ${timestamp}, recursion count ${recursion.count}, reason: ${recursion.reason}...`
|
||||
);
|
||||
|
||||
if (recursion.count > MAX_RECURSION) {
|
||||
throw new Error(
|
||||
`sendToGroupViaSenderKey/${logId}: Too much recursion! Count is at ${recursion.count}`
|
||||
`${logId}: Too much recursion! Count is at ${recursion.count}`
|
||||
);
|
||||
}
|
||||
|
||||
const groupId = sendTarget.getGroupId();
|
||||
if (!sendTarget.isValid()) {
|
||||
throw new Error(
|
||||
`sendToGroupViaSenderKey/${logId}: sendTarget is not valid!`
|
||||
);
|
||||
throw new Error(`${logId}: sendTarget is not valid!`);
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -319,9 +317,7 @@ export async function sendToGroupViaSenderKey(
|
|||
contentHint !== ContentHint.RESENDABLE &&
|
||||
contentHint !== ContentHint.IMPLICIT
|
||||
) {
|
||||
throw new Error(
|
||||
`sendToGroupViaSenderKey/${logId}: Invalid contentHint ${contentHint}`
|
||||
);
|
||||
throw new Error(`${logId}: Invalid contentHint ${contentHint}`);
|
||||
}
|
||||
|
||||
strictAssert(
|
||||
|
@ -334,9 +330,7 @@ export async function sendToGroupViaSenderKey(
|
|||
const senderKeyInfo = sendTarget.getSenderKeyInfo();
|
||||
|
||||
if (!senderKeyInfo) {
|
||||
log.info(
|
||||
`sendToGroupViaSenderKey/${logId}: Adding initial sender key info`
|
||||
);
|
||||
log.info(`${logId}: Adding initial sender key info`);
|
||||
await sendTarget.saveSenderKeyInfo({
|
||||
createdAtDate: Date.now(),
|
||||
distributionId: generateUuid(),
|
||||
|
@ -350,9 +344,7 @@ export async function sendToGroupViaSenderKey(
|
|||
const EXPIRE_DURATION = getSenderKeyExpireDuration();
|
||||
if (isOlderThan(senderKeyInfo.createdAtDate, EXPIRE_DURATION)) {
|
||||
const { createdAtDate } = senderKeyInfo;
|
||||
log.info(
|
||||
`sendToGroupViaSenderKey/${logId}: Resetting sender key; ${createdAtDate} is too old`
|
||||
);
|
||||
log.info(`${logId}: Resetting sender key; ${createdAtDate} is too old`);
|
||||
await resetSenderKey(sendTarget);
|
||||
|
||||
// Restart here because we updated senderKeyInfo
|
||||
|
@ -419,7 +411,7 @@ export async function sendToGroupViaSenderKey(
|
|||
const senderKeyRecipients = getServiceIdsFromDevices(devicesForSenderKey);
|
||||
const normalSendRecipients = getServiceIdsFromDevices(devicesForNormalSend);
|
||||
log.info(
|
||||
`sendToGroupViaSenderKey/${logId}:` +
|
||||
`${logId}:` +
|
||||
` ${senderKeyRecipients.length} accounts for sender key (${devicesForSenderKey.length} devices),` +
|
||||
` ${normalSendRecipients.length} accounts for normal send (${devicesForNormalSend.length} devices)`
|
||||
);
|
||||
|
@ -427,7 +419,7 @@ export async function sendToGroupViaSenderKey(
|
|||
// 5. Ensure we have enough recipients
|
||||
if (senderKeyRecipients.length < 2) {
|
||||
throw new Error(
|
||||
`sendToGroupViaSenderKey/${logId}: Not enough recipients for Sender Key message. Failing over.`
|
||||
`${logId}: Not enough recipients for Sender Key message. Failing over.`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -460,7 +452,7 @@ export async function sendToGroupViaSenderKey(
|
|||
// have our sender key before we send sender key messages to them.
|
||||
if (newToMemberServiceIds.length > 0) {
|
||||
log.info(
|
||||
`sendToGroupViaSenderKey/${logId}: Sending sender key to ${
|
||||
`${logId}: Sending sender key to ${
|
||||
newToMemberServiceIds.length
|
||||
} members: ${JSON.stringify(newToMemberServiceIds)}`
|
||||
);
|
||||
|
@ -583,7 +575,7 @@ export async function sendToGroupViaSenderKey(
|
|||
);
|
||||
} else {
|
||||
log.error(
|
||||
`sendToGroupViaSenderKey/${logId}: Server returned unexpected 200 response ${JSON.stringify(
|
||||
`${logId}: Server returned unexpected 200 response ${JSON.stringify(
|
||||
parsed.error.flatten()
|
||||
)}`
|
||||
);
|
||||
|
@ -637,7 +629,7 @@ export async function sendToGroupViaSenderKey(
|
|||
const brokenAccount = window.ConversationController.get(name);
|
||||
if (brokenAccount) {
|
||||
log.warn(
|
||||
`sendToGroupViaSenderKey/${logId}: Disabling sealed sender for ${brokenAccount.idForLogging()}`
|
||||
`${logId}: Disabling sealed sender for ${brokenAccount.idForLogging()}`
|
||||
);
|
||||
brokenAccount.set({ sealedSender: SEALED_SENDER.DISABLED });
|
||||
await DataWriter.updateConversation(brokenAccount.attributes);
|
||||
|
@ -652,7 +644,7 @@ export async function sendToGroupViaSenderKey(
|
|||
}
|
||||
|
||||
log.error(
|
||||
`sendToGroupViaSenderKey/${logId}: Returned unexpected error code: ${
|
||||
`${logId}: Returned unexpected error code: ${
|
||||
error.code
|
||||
}, error class: ${typeof error}`
|
||||
);
|
||||
|
@ -1381,11 +1373,8 @@ async function fetchKeysForServiceId(
|
|||
devices: Array<number> | null,
|
||||
groupSendEndorsementState: GroupSendEndorsementState | null
|
||||
): Promise<void> {
|
||||
log.info(
|
||||
`fetchKeysForServiceId: Fetching ${
|
||||
devices || 'all'
|
||||
} devices for ${serviceId}`
|
||||
);
|
||||
const logId = `fetchKeysForServiceId/${serviceId}`;
|
||||
log.info(`${logId}: Fetching ${devices || 'all'} devices`);
|
||||
|
||||
if (!window.textsecure?.messaging?.server) {
|
||||
throw new Error('fetchKeysForServiceId: No server available!');
|
||||
|
@ -1442,9 +1431,7 @@ async function fetchKeysForServiceId(
|
|||
onFailedToSendWithEndorsements(error as Error);
|
||||
}
|
||||
log.error(
|
||||
`fetchKeysForServiceId: Error fetching ${
|
||||
devices || 'all'
|
||||
} devices for ${serviceId}`,
|
||||
`${logId}: Error fetching ${devices || 'all'} devices`,
|
||||
Errors.toLogFormat(error)
|
||||
);
|
||||
throw error;
|
||||
|
|
Loading…
Reference in a new issue