From 30cad2f2b0058ebdacc1d8e9cf7de34abc10c052 Mon Sep 17 00:00:00 2001 From: automated-signal <37887102+automated-signal@users.noreply.github.com> Date: Wed, 28 May 2025 08:56:32 -0500 Subject: [PATCH] Drop pni call messages Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> --- ts/services/calling.ts | 10 +++- ts/test-mock/pnp/calling_test.ts | 98 ++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 ts/test-mock/pnp/calling_test.ts diff --git a/ts/services/calling.ts b/ts/services/calling.ts index d232052eee..09daf35f1f 100644 --- a/ts/services/calling.ts +++ b/ts/services/calling.ts @@ -139,7 +139,7 @@ import { } from '../util/callDisposition'; import { isNormalNumber } from '../util/isNormalNumber'; import type { AciString, ServiceIdString } from '../types/ServiceId'; -import { isServiceIdString } from '../types/ServiceId'; +import { isServiceIdString, isPniString } from '../types/ServiceId'; import { isSignalConnection } from '../util/getSignalConnections'; import { toAdminKeyBytes } from '../util/callLinks'; import { @@ -2807,6 +2807,14 @@ export class CallingClass { callingMessage.offer && !conversation.getAccepted({ ignoreEmptyConvo: true }) ) { + if (isPniString(envelope.destinationServiceId)) { + log.info( + `${logId}: Conversation was not approved by user; ` + + 'ignoring call message on PNI.' + ); + return; + } + log.info( `${logId}: Conversation was not approved by user; ` + 'rejecting call message.' diff --git a/ts/test-mock/pnp/calling_test.ts b/ts/test-mock/pnp/calling_test.ts new file mode 100644 index 0000000000..52f8b4a1df --- /dev/null +++ b/ts/test-mock/pnp/calling_test.ts @@ -0,0 +1,98 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import chai, { assert } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { type PrimaryDevice, ServiceIdKind } from '@signalapp/mock-server'; +import createDebug from 'debug'; + +import * as durations from '../../util/durations'; +import { Bootstrap } from '../bootstrap'; +import type { App } from '../bootstrap'; +import { acceptConversation } from '../helpers'; + +chai.use(chaiAsPromised); + +export const debug = createDebug('mock:test:pnp:calling'); + +describe('pnp/calling', function (this: Mocha.Suite) { + this.timeout(durations.MINUTE); + + let bootstrap: Bootstrap; + let app: App; + let alice: PrimaryDevice; + let stranger: PrimaryDevice; + + beforeEach(async () => { + bootstrap = new Bootstrap({ contactCount: 0 }); + await bootstrap.init(); + + const { server } = bootstrap; + + alice = await server.createPrimaryDevice({ + profileName: 'Alice', + }); + stranger = await server.createPrimaryDevice({ + profileName: 'Stranger', + }); + + app = await bootstrap.link(); + + const { desktop } = bootstrap; + + const ourPniKey = await desktop.popSingleUseKey(ServiceIdKind.PNI); + await stranger.addSingleUseKey(desktop, ourPniKey, ServiceIdKind.PNI); + + const ourAciKey = await desktop.popSingleUseKey(ServiceIdKind.ACI); + await alice.addSingleUseKey(desktop, ourAciKey, ServiceIdKind.ACI); + }); + + afterEach(async function (this: Mocha.Context) { + await bootstrap.maybeSaveLogs(this.currentTest, app); + await app.close(); + await bootstrap.teardown(); + }); + + it('should ignore calling message received on PNI', async () => { + const { desktop } = bootstrap; + + const window = await app.getWindow(); + const leftPane = window.locator('#LeftPane'); + + debug('Sending a calling message from stranger to PNI'); + await stranger.sendRaw( + desktop, + { + callMessage: { + offer: { + opaque: Buffer.alloc(1), + }, + }, + }, + { + timestamp: bootstrap.getTimestamp(), + serviceIdKind: ServiceIdKind.PNI, + } + ); + + debug('Sending a message from a known contact'); + await alice.sendText(desktop, 'hey', { + withProfileKey: true, + }); + + debug('Open conversation with a known contact'); + await leftPane.locator(`[data-testid="${alice.toContact().aci}"]`).click(); + + debug('Accept conversation from a known contact'); + await acceptConversation(window); + + debug('Wait for a message from a known contact'); + await alice.waitForMessage(); + + debug('Verify no session with stranger'); + await assert.isRejected( + stranger.sendText(desktop, 'Hello on ACI'), + /session with.*not found/ + ); + }); +});