diff --git a/ts/services/storage.ts b/ts/services/storage.ts index f4eec0eecffa..d00142dc752a 100644 --- a/ts/services/storage.ts +++ b/ts/services/storage.ts @@ -1515,7 +1515,7 @@ async function processRemoteRecords( }); // Find remote contact records that: - // - Have `remote.pni === remote.serviceUuid` and have `remote.serviceE164` + // - Have `remote.pni` and have `remote.serviceE164` // - Match local contact that has `aci`. const splitPNIContacts = new Array(); prunedStorageItems = prunedStorageItems.filter(item => { diff --git a/ts/test-mock/pnp/merge_test.ts b/ts/test-mock/pnp/merge_test.ts index 1e2975a6be8e..39d243140b1f 100644 --- a/ts/test-mock/pnp/merge_test.ts +++ b/ts/test-mock/pnp/merge_test.ts @@ -229,103 +229,116 @@ describe('pnp/merge', function (this: Mocha.Suite) { }); } - it('accepts storage service contact splitting', async () => { - const { phone } = bootstrap; + for (const withPniContact of [false, true]) { + const testName = + 'accepts storage service contact splitting ' + + `${withPniContact ? 'with PNI contact' : 'without PNI contact'}`; - debug( - 'removing both contacts from storage service, adding one combined contact' - ); - { - const state = await phone.expectStorageState('consistency check'); - await phone.setStorageState( - state.mergeContact(pniContact, { - identityState: Proto.ContactRecord.IdentityState.DEFAULT, - whitelisted: true, - identityKey: pniContact.publicKey.serialize(), - profileKey: pniContact.profileKey.serialize(), - }) + // eslint-disable-next-line no-loop-func + it(testName, async () => { + const { phone } = bootstrap; + + debug( + 'removing both contacts from storage service, adding one combined contact' ); - await phone.sendFetchStorage({ - timestamp: bootstrap.getTimestamp(), - }); - } + { + const state = await phone.expectStorageState('consistency check'); + await phone.setStorageState( + state.mergeContact(pniContact, { + identityState: Proto.ContactRecord.IdentityState.DEFAULT, + whitelisted: true, + identityKey: pniContact.publicKey.serialize(), + profileKey: pniContact.profileKey.serialize(), + }) + ); + await phone.sendFetchStorage({ + timestamp: bootstrap.getTimestamp(), + }); + } - const window = await app.getWindow(); - const leftPane = window.locator('#LeftPane'); + const window = await app.getWindow(); + const leftPane = window.locator('#LeftPane'); - debug('opening conversation with the merged contact'); - await leftPane - .locator( - `[data-testid="${pniContact.device.aci}"] >> ` + - `"${pniContact.profileName}"` - ) - .click(); + debug('opening conversation with the merged contact'); + await leftPane + .locator( + `[data-testid="${pniContact.device.aci}"] >> ` + + `"${pniContact.profileName}"` + ) + .click(); - await window.locator('.module-conversation-hero').waitFor(); + await window.locator('.module-conversation-hero').waitFor(); - debug('Send message to merged contact'); - { - const compositionInput = await app.waitForEnabledComposer(); + debug('Send message to merged contact'); + { + const compositionInput = await app.waitForEnabledComposer(); - await compositionInput.type('Hello merged'); - await compositionInput.press('Enter'); - } + await compositionInput.type('Hello merged'); + await compositionInput.press('Enter'); + } - debug('Split contact and mark ACI as unregistered'); - { - let state = await phone.expectStorageState('consistency check'); + debug('Split contact and mark ACI as unregistered'); + { + let state = await phone.expectStorageState('consistency check'); - state = state.updateContact(pniContact, { - pni: undefined, - serviceE164: undefined, - unregisteredAtTimestamp: Long.fromNumber(bootstrap.getTimestamp()), - }); + state = state.updateContact(pniContact, { + pni: undefined, + serviceE164: undefined, + unregisteredAtTimestamp: Long.fromNumber(bootstrap.getTimestamp()), + }); - state = state.addContact( - pniContact, - { - identityState: Proto.ContactRecord.IdentityState.DEFAULT, - whitelisted: true, + if (withPniContact) { + state = state.addContact( + pniContact, + { + identityState: Proto.ContactRecord.IdentityState.DEFAULT, + whitelisted: true, - identityKey: pniIdentityKey, + identityKey: pniIdentityKey, - serviceE164: pniContact.device.number, - givenName: 'PNI Contact', - }, - ServiceIdKind.PNI - ); + serviceE164: pniContact.device.number, + givenName: 'PNI Contact', + }, + ServiceIdKind.PNI + ); + } - state = state.pin(pniContact, ServiceIdKind.PNI); + state = state.pin(pniContact, ServiceIdKind.PNI); - await phone.setStorageState(state); - await phone.sendFetchStorage({ - timestamp: bootstrap.getTimestamp(), - }); - } + await phone.setStorageState(state); + await phone.sendFetchStorage({ + timestamp: bootstrap.getTimestamp(), + }); + } - debug('Wait for pni contact to appear'); - await leftPane - .locator(`[data-testid="${pniContact.device.pni}"]`) - .waitFor(); + debug('Wait for pni contact to appear'); + await leftPane + .locator(`[data-testid="${pniContact.device.pni}"]`) + .waitFor(); - debug('Verify that the message is in the ACI conversation'); - { - // Should have both PNI and ACI messages - await window.locator('.module-message__text >> "Hello merged"').waitFor(); + debug('Verify that the message is in the ACI conversation'); + { + // Should have both PNI and ACI messages + await window + .locator('.module-message__text >> "Hello merged"') + .waitFor(); - const messages = window.locator('.module-message__text'); - assert.strictEqual(await messages.count(), 1, 'message count'); - } + const messages = window.locator('.module-message__text'); + assert.strictEqual(await messages.count(), 1, 'message count'); + } - debug('Open PNI conversation'); - await leftPane.locator(`[data-testid="${pniContact.device.pni}"]`).click(); + debug('Open PNI conversation'); + await leftPane + .locator(`[data-testid="${pniContact.device.pni}"]`) + .click(); - debug('Verify absence of messages in the PNI conversation'); - { - const messages = window.locator('.module-message__text'); - assert.strictEqual(await messages.count(), 0, 'message count'); - } - }); + debug('Verify absence of messages in the PNI conversation'); + { + const messages = window.locator('.module-message__text'); + assert.strictEqual(await messages.count(), 0, 'message count'); + } + }); + } it('splits contact when ACI becomes unregistered', async () => { const { phone, server } = bootstrap; diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index dd200fb2c925..c2b5f9a35d61 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -640,8 +640,7 @@ export type CapabilitiesType = { pni: boolean; }; export type CapabilitiesUploadType = { - // true in staging, false in production - pni: boolean; + pni: true; }; type StickerPackManifestType = Uint8Array;