Skip to content

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

Closed
meaadore1221-afk wants to merge 2 commits intoopenclaw:mainfrom
ricklfrk:fix/signal-uuid-allowlist
Closed

fix: Signal UUID allowlist entries silently fail when sourceNumber is present#10958
meaadore1221-afk wants to merge 2 commits intoopenclaw:mainfrom
ricklfrk:fix/signal-uuid-allowlist

Conversation

@meaadore1221-afk
Copy link
Copy Markdown
Contributor

@meaadore1221-afk meaadore1221-afk commented Feb 7, 2026

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

Greptile Overview

Greptile Summary

  • 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.

Confidence Score: 4/5

  • 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

(4/5) You can add custom instructions or style guidelines for the agent here!

@openclaw-barnacle openclaw-barnacle bot added the channel: signal Channel integration: signal label Feb 7, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +18 to +25
it("returns phone sender without uuid when sourceUuid is missing", () => {
const sender = resolveSignalSender({ sourceNumber: "+15550001111" });
expect(sender).toEqual({
kind: "phone",
raw: "+15550001111",
e164: "+15550001111",
uuid: undefined,
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect expectation for uuid

resolveSignalSender sets uuid with params.sourceUuid?.trim() || undefined, so when sourceUuid is missing it won’t add the uuid property at all. This test currently expects uuid: undefined, which will fail strict toEqual because the actual object won’t have that key. Update the expectation to omit uuid (or use toMatchObject / assert uuid is undefined via optional chaining).

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/signal/identity.test.ts
Line: 18:25

Comment:
**Incorrect expectation for uuid**

`resolveSignalSender` sets `uuid` with `params.sourceUuid?.trim() || undefined`, so when `sourceUuid` is missing it won’t add the `uuid` property at all. This test currently expects `uuid: undefined`, which will fail strict `toEqual` because the actual object won’t have that key. Update the expectation to omit `uuid` (or use `toMatchObject` / assert `uuid` is `undefined` via optional chaining).

How can I resolve this? If you propose a fix, please make it concise.

@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels Feb 21, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle bot added the stale Marked as stale due to inactivity label Mar 8, 2026
@openclaw-barnacle
Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: signal Channel integration: signal stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant