mirror of
https://github.com/AsamK/signal-cli.git
synced 2026-10-27 08:59:55 +00:00
Accept group invitations addressed to the PNI (#2146)
An invitation by phone number lists the account's PNI as the pending member. acceptInvite compared pending members only with the self ACI address and failed with 'Cannot find service ID for self to accept invite'. It now matches either the ACI or the PNI, makes the change as the ACI, and for a PNI promotion decrypts the server's signed change, since the locally built action has no member ciphertexts to decrypt.
This commit is contained in:
parent
1da2a51c1e
commit
c3b0fe902e
@ -480,15 +480,16 @@ class GroupV2Helper {
|
||||
}
|
||||
|
||||
// We need to accept the invite with the ACI or PNI that was used for the invitation
|
||||
final var selfAddress = context.getRecipientHelper().resolveSignalServiceAddress(selfRecipientId);
|
||||
final var account = context.getAccount();
|
||||
final var selfServiceId = groupInfoV2.getPendingMemberAddresses()
|
||||
.stream()
|
||||
.filter(s -> s.matches(selfAddress))
|
||||
.map(SignalServiceAddress::getServiceId)
|
||||
.filter(s -> s.equals(account.getAci()) || s.equals(account.getPni()))
|
||||
.findFirst();
|
||||
if (selfServiceId.isEmpty()) {
|
||||
throw new IOException("Cannot find service ID for self to accept invite");
|
||||
}
|
||||
final var serviceId = selfServiceId.get().getServiceId();
|
||||
final var serviceId = selfServiceId.get();
|
||||
|
||||
final GroupChange.Actions.Builder change;
|
||||
if (serviceId instanceof ACI) {
|
||||
@ -497,7 +498,8 @@ class GroupV2Helper {
|
||||
change = groupOperations.createAcceptPniInviteChange(profileKeyCredential);
|
||||
}
|
||||
|
||||
change.sourceUserId(serviceId.toByteString());
|
||||
// The change is made by the account's ACI, also when it promotes a PNI invitation
|
||||
change.sourceUserId(account.getAci().toByteString());
|
||||
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
@ -634,6 +636,22 @@ class GroupV2Helper {
|
||||
final DecryptedGroupChange decryptedChange;
|
||||
final DecryptedGroup decryptedGroupState;
|
||||
|
||||
if (!changeActions.promote_members_pending_pni_aci_profile_key.isEmpty()) {
|
||||
// The server fills in the ACI and PNI ciphertexts of a PNI promotion, so decrypt its signed change
|
||||
final var signedGroupChange = dependencies.getGroupsV2Api()
|
||||
.patchGroup(changeActions, getGroupAuthForToday(groupSecretParams), Optional.empty());
|
||||
final var groupId = groupSecretParams.getPublicParams().getGroupIdentifier();
|
||||
try {
|
||||
decryptedChange = groupOperations.decryptChange(signedGroupChange.group_change,
|
||||
DecryptChangeVerificationMode.verify(groupId)).orElseThrow();
|
||||
decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange);
|
||||
} catch (VerificationFailedException | InvalidGroupStateException | NotAbleToApplyGroupV2ChangeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
groupInfoV2.setGroup(decryptedGroupState);
|
||||
return new Pair<>(decryptedGroupState, signedGroupChange);
|
||||
}
|
||||
|
||||
try {
|
||||
decryptedChange = groupOperations.decryptChange(changeActions, getSelfAci());
|
||||
decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user