← Back to PRs

#10958: fix: Signal UUID allowlist entries silently fail when sourceNumber is present

by meaadore1221-afk open 2026-02-07 07:06 View on GitHub →
channel: signal stale
## Problem When a Signal envelope contains **both** `sourceNumber` and `sourceUuid` (which is the common case for registered Signal users), `resolveSignalSender` always returns a sender with `kind: "phone"` because it prioritizes `sourceNumber`. The `sourceUuid` is discarded entirely. This means that any allowlist entry using the `uuid:` prefix format (e.g. `"uuid:cb274c30-17ce-49ee-97c6-55dd9ce14595"`) will **never match** a phone-kind sender, because `isSignalSenderAllowed` performs strict kind-matching: a `uuid` entry only matches a `uuid` sender, and a `phone` entry only matches a `phone` sender. **Impact:** All DM messages from users whose allowlist entries use `uuid:` format are silently dropped — no error, no log, no pairing prompt. The user simply never receives a response. ## Root Cause 1. **`resolveSignalSender`** (line 35): returns `{ kind: "phone" }` whenever `sourceNumber` is present, throwing away `sourceUuid`. 2. **`isSignalSenderAllowed`** (line 112): only compares `entry.kind === "uuid" && sender.kind === "uuid"`, so a `uuid:` allowlist entry can never match a `kind: "phone"` sender. ## Fix Three targeted changes in `src/signal/identity.ts`: 1. **`SignalSender` type**: add optional `uuid?: string` field to the phone variant, so both identifiers can coexist. 2. **`resolveSignalSender`**: when `sourceNumber` is present, also preserve `sourceUuid` on the returned phone sender. 3. **`isSignalSenderAllowed`**: when a `uuid` allowlist entry is checked against a `phone` sender, also compare against `sender.uuid` (cross-kind matching). ## Testing - Added `src/signal/identity.test.ts` with 10 tests covering: - `resolveSignalSender` preserves UUID alongside phone number - `resolveSignalSender` falls back to UUID-only when no phone - `isSignalSenderAllowed` phone-to-phone matching (unchanged) - `isSignalSenderAllowed` uuid-to-uuid matching (unchanged) - **`isSignalSenderAllowed` uuid entry vs phone sender with uuid** (the fix) - `isSignalSenderAllowed` uuid entry vs phone sender without uuid (rejects correctly) - Wildcard and empty allowlist edge cases - All 47 existing Signal tests pass with no regressions. Made with [Cursor](https://cursor.com) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> - Preserve `sourceUuid` alongside `sourceNumber` by extending the phone variant of `SignalSender` with an optional `uuid` field. - Update `resolveSignalSender` to include `uuid` on phone senders when present, instead of discarding it. - Update `isSignalSenderAllowed` to allow `uuid:` allowlist entries to match phone senders that carry a UUID (cross-kind match). - Add a new `identity.test.ts` suite covering sender resolution and allowlist matching, including the cross-kind UUID case. <h3>Confidence Score: 4/5</h3> - Safe to merge after fixing a failing unit test expectation. - The production change is small and directly addresses the reported mismatch by preserving UUIDs and allowing cross-kind UUID matching. The only concrete issue found is in the new test suite: it expects a `uuid: undefined` key that the implementation does not emit, which should cause that test to fail. After correcting the test, the change set looks consistent and low-risk. - src/signal/identity.test.ts <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs