Skip to content

[webhooks] add destination number in *:received payload#319

Merged
capcom6 merged 1 commit intomasterfrom
webhooks/sms-received-destination-number
Feb 28, 2026
Merged

[webhooks] add destination number in *:received payload#319
capcom6 merged 1 commit intomasterfrom
webhooks/sms-received-destination-number

Conversation

@capcom6
Copy link
Copy Markdown
Owner

@capcom6 capcom6 commented Feb 18, 2026

Summary by CodeRabbit

  • New Features

    • Webhooks now emit per-destination recipient events and include explicit sender and recipient fields.
    • Improved phone-number resolution on multi‑SIM devices with permission-validated lookup.
  • Refactor

    • Replaced single phoneNumber with sender/recipient pairs across SMS/MMS event payloads; simNumber handling standardized and timestamps added where applicable.
  • Deprecated

    • Legacy phoneNumber property marked deprecated; use sender or recipient instead.
  • Documentation

    • OpenAPI schema updated to reflect new payload shapes, servers, security schemes, and webhook callbacks.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds SubscriptionsHelper.getPhoneNumber(context, simSlotIndex) and changes SMS/MMS flows to populate explicit sender and recipient (plus simNumber) in webhook payloads; updates payload models and the OpenAPI spec to reflect new webhook event/payload shapes and callbacks.

Changes

Cohort / File(s) Summary
Subscriptions helper
app/src/main/java/me/capcom/smsgateway/helpers/SubscriptionsHelper.kt
Adds fun getPhoneNumber(context: Context, simSlotIndex: Int): String? with READ_PHONE_STATE permission guard, SDK checks, and SubscriptionManager lookup to resolve phone number by SIM slot.
Receiver logic
app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt
Derives simSlotIndex from message.subscriptionId, computes simNumber, resolves recipient and sender; replaces previous phoneNumber usages with sender/recipient in SmsReceived, SmsDataReceived, and MmsReceived payloads.
Webhook dispatch
app/src/main/java/me/capcom/smsgateway/modules/webhooks/EventsReceiver.kt
Injects Android Context, calls SubscriptionsHelper.getPhoneNumber(context, simIndex - 1) to compute sender, iterates destinations as recipient, and emits payloads populated with sender, recipient, and simNumber.
Payload models
app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/MessageEventPayload.kt, .../SmsEventPayload.kt, .../MmsReceivedPayload.kt
Replaces phoneNumber with nullable sender and recipient (adds deprecated phoneNumber alias); updates SmsEventPayload and all subclasses to accept/forward sender/recipient; adjusts MmsReceivedPayload constructor/order and adds receivedAt.
API spec
app/src/main/assets/api/swagger.json
Extensive OpenAPI changes: new/renamed schemas and enums, webhook callbacks and event payloads added (SmsReceived, SmsSent, SmsDelivered, SmsFailed, SmsDataReceived, MmsReceived, SystemPing), servers/security updates, and many schema restructurings to align with sender/recipient model.

Sequence Diagram

sequenceDiagram
    participant RC as ReceiverService
    participant WH as EventsReceiver
    participant SH as SubscriptionsHelper
    participant SM as SubscriptionManager
    participant WEB as WebhookEndpoint

    RC->>RC: Parse incoming message (address, destinations, subscriptionId)
    RC->>WH: Emit event (simNumber, destinations, message data)
    loop per destination
        WH->>SH: getPhoneNumber(context, simNumber - 1)
        SH->>SM: query activeSubscriptionInfoList
        SM-->>SH: subscription info / phoneNumber
        SH-->>WH: sender (nullable)
        WH->>WEB: POST webhook payload (sender, recipient, simNumber, event)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding destination number (recipient field) to received SMS/MMS webhook payloads, which is the primary focus of the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch webhooks/sms-received-destination-number

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/SmsEventPayload.kt (1)

5-11: ⚠️ Potential issue | 🔴 Critical

Type mismatch: simNumber: Int? passed to non-null Int parameter in MessageEventPayload

SmsEventPayload declares simNumber: Int? (line 8) but passes it to MessageEventPayload which expects simNumber: Int (non-null). This is a compilation error on top of the argument count mismatch already noted in MessageEventPayload.kt.

If simNumber truly needs to be nullable in SmsEventPayload (EventsReceiver passes event.simNumber which appears nullable), then either MessageEventPayload.simNumber should also be Int?, or the coercion to a default (e.g., simNumber ?: 0 as done in ReceiverService) should happen here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/SmsEventPayload.kt`
around lines 5 - 11, SmsEventPayload is declaring simNumber as nullable
(simNumber: Int?) but passes it to the base class MessageEventPayload which
expects a non-null Int; fix by either changing MessageEventPayload.simNumber to
Int? to accept nulls, or coerce the nullable here before calling the superclass
(e.g., pass simNumber ?: <default>) so the types align; update the constructor
signature in MessageEventPayload or the SmsEventPayload constructor call
accordingly and ensure all callers (e.g., EventsReceiver) remain consistent with
the chosen approach.
🧹 Nitpick comments (2)
app/src/main/java/me/capcom/smsgateway/modules/webhooks/EventsReceiver.kt (2)

43-49: Sender lookup logic is clean; consider using null over empty string

The fallback chain (subscriptionId → simNumber) is well-structured. However, defaulting sender to "" (lines 59, 68, 78) when the device's own number can't be determined produces an empty string in the JSON payload. A null value would more clearly convey "unknown" to webhook consumers.

This would require changing sender to String? in the payload classes, so it's a design decision.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/me/capcom/smsgateway/modules/webhooks/EventsReceiver.kt`
around lines 43 - 49, Change the sender fallback so it yields null instead of an
empty string: when resolving sender in EventsReceiver.kt (the local val sender
computed from event.subscriptionId and event.simNumber using
SubscriptionsHelper.getPhoneNumberBySubscriptionId / getPhoneNumber), return
null if no phone number is found rather than "" and update any webhook payload
data classes that hold sender to use a nullable String (String?) so the
serialized JSON emits null for unknown senders.

51-88: phoneNumber and destination are assigned the same value for outgoing events

For all three event types (SmsSent, SmsDelivered, SmsFailed), both phoneNumber and destination are set to the loop variable destination (the recipient number from event.phoneNumbers). While this maintains backward compatibility for phoneNumber, it's redundant and may confuse consumers.

Is the intent that phoneNumber remains the backward-compatible "other party" field, while destination is the newly named equivalent? If so, this is fine but worth a code comment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/me/capcom/smsgateway/modules/webhooks/EventsReceiver.kt`
around lines 51 - 88, The loop in EventsReceiver.kt sets both
SmsEventPayload.phoneNumber and destination to the same loop variable
destination for SmsSent/SmsDelivered/SmsFailed; add a brief code comment above
the payload construction (near the event.phoneNumbers.forEach and before
SmsEventPayload.SmsSent/Delivered/Failed) clarifying intent—e.g., that
phoneNumber is preserved for backward compatibility as the "other party" field
while destination is the new explicit recipient field—so future readers know
this duplication is intentional (reference webhookEventType, SmsEventPayload.*
classes, event.phoneNumbers, and the get<WebHooksService>().emit call).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/me/capcom/smsgateway/helpers/SubscriptionsHelper.kt`:
- Around line 88-121: Both getPhoneNumber and getPhoneNumberBySubscriptionId
risk NPEs because subscriptionManager.activeSubscriptionInfoList can be null and
also use deprecated SubscriptionInfo.number on API 33+; update both functions
(getPhoneNumber and getPhoneNumberBySubscriptionId) to safely handle a null
activeSubscriptionInfoList by using the null-safe operator (e.g.,
activeSubscriptionInfoList?.find { ... }) before calling .find and .number, and
for API 33+ use SubscriptionManager.getPhoneNumber(subscriptionId) when
available (falling back to SubscriptionInfo.number only for older APIs) while
preserving the permission checks and existing return behavior.

In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/MessageEventPayload.kt`:
- Around line 3-12: The constructor parameter list of MessageEventPayload does
not match its subclasses: either reintroduce the removed phoneNumber parameter
in MessageEventPayload's constructor (kept as non-val if you only need it for
serialization) and preserve the deprecated phoneNumber getter, or update the
subclass super calls in SmsEventPayload and MmsReceivedPayload to pass only
(messageId, sender, simNumber, destination) and fix simNumber nullability
(change SmsEventPayload.simNumber: Int? to Int or make
MessageEventPayload.simNumber nullable). Locate MessageEventPayload,
SmsEventPayload, and MmsReceivedPayload and choose one approach: (A) add back
phoneNumber parameter to MessageEventPayload signature and keep the deprecated
phoneNumber getter, or (B) remove the extra argument from subclass super(...)
invocations and align simNumber types consistently between SmsEventPayload and
MessageEventPayload.
- Around line 14-16: Update the reference comment in MessageEventPayload.kt to
fix the typo: change "desing.md" to "design.md" in the comment block (the
Javadoc-style reference at the top of the file associated with the
MessageEventPayload class) so the documented path correctly reads
dev-docs/android-app/tasks/2026-02-17_sms-received-webhook-destination-number/01-design.md.

In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/MmsReceivedPayload.kt`:
- Around line 5-20: The MmsReceivedPayload constructor currently includes an
unused phoneNumber parameter and calls the superclass with incorrect arguments;
update the MmsReceivedPayload declaration to remove the phoneNumber constructor
parameter and change the superclass invocation to MessageEventPayload(messageId,
sender, simNumber, destination) so the parameter order matches the parent
constructor; keep the deprecated phoneNumber property (val phoneNumber: String
get() = sender) as-is to preserve the intended API.

In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/SmsEventPayload.kt`:
- Around line 17-25: The SmsSent payload currently causes phoneNumber and
destination to carry the same recipient value — update the
construction/definition so semantics are consistent: either make
SmsSent.phoneNumber represent the device/sender number (match
MessageEventPayload behavior) or change EventsReceiver.kt to pass the device
number into the phoneNumber parameter. Locate the SmsSent class and the code in
EventsReceiver.kt that constructs SmsSent and choose one fix: (a) alter SmsSent
constructor signature/field ordering so phoneNumber is the device/sender and
destination is the recipient, or (b) keep the current SmsSent signature but
change the call site in EventsReceiver.kt to pass sender for phoneNumber and
recipient for destination; ensure serialized JSON fields reflect the intended
semantics and update any dependent code/tests accordingly.

---

Outside diff comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/SmsEventPayload.kt`:
- Around line 5-11: SmsEventPayload is declaring simNumber as nullable
(simNumber: Int?) but passes it to the base class MessageEventPayload which
expects a non-null Int; fix by either changing MessageEventPayload.simNumber to
Int? to accept nulls, or coerce the nullable here before calling the superclass
(e.g., pass simNumber ?: <default>) so the types align; update the constructor
signature in MessageEventPayload or the SmsEventPayload constructor call
accordingly and ensure all callers (e.g., EventsReceiver) remain consistent with
the chosen approach.

---

Nitpick comments:
In `@app/src/main/java/me/capcom/smsgateway/modules/webhooks/EventsReceiver.kt`:
- Around line 43-49: Change the sender fallback so it yields null instead of an
empty string: when resolving sender in EventsReceiver.kt (the local val sender
computed from event.subscriptionId and event.simNumber using
SubscriptionsHelper.getPhoneNumberBySubscriptionId / getPhoneNumber), return
null if no phone number is found rather than "" and update any webhook payload
data classes that hold sender to use a nullable String (String?) so the
serialized JSON emits null for unknown senders.
- Around line 51-88: The loop in EventsReceiver.kt sets both
SmsEventPayload.phoneNumber and destination to the same loop variable
destination for SmsSent/SmsDelivered/SmsFailed; add a brief code comment above
the payload construction (near the event.phoneNumbers.forEach and before
SmsEventPayload.SmsSent/Delivered/Failed) clarifying intent—e.g., that
phoneNumber is preserved for backward compatibility as the "other party" field
while destination is the new explicit recipient field—so future readers know
this duplication is intentional (reference webhookEventType, SmsEventPayload.*
classes, event.phoneNumbers, and the get<WebHooksService>().emit call).

Comment thread app/src/main/java/me/capcom/smsgateway/helpers/SubscriptionsHelper.kt Outdated
@capcom6 capcom6 force-pushed the webhooks/sms-received-destination-number branch from ffd25b8 to dbfccd5 Compare February 19, 2026 01:08
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/MessageEventPayload.kt`:
- Around line 5-10: The Depracation ReplaceWith("recipient") on the
MessageEventPayload property phoneNumber is misleading for incoming events
because some subclasses (e.g., SmsReceived, SmsDataReceived, MmsReceivedPayload)
pass sender into phoneNumber; update the deprecation to avoid incorrect
automated replacements by either removing the ReplaceWith parameter entirely
from the `@Deprecated` annotation on val phoneNumber or change the message to
explicitly state direction-dependent replacement (e.g., "Use sender for received
events or recipient for sent events") and remove the ReplaceWith argument;
locate the phoneNumber property in MessageEventPayload and adjust the
`@Deprecated` annotation accordingly so callers aren’t auto-migrated to recipient
when they should use sender.

---

Duplicate comments:
In `@app/src/main/java/me/capcom/smsgateway/helpers/SubscriptionsHelper.kt`:
- Around line 97-103: subscriptionManager.activeSubscriptionInfoList may be null
on older SDKs; update every occurrence of
subscriptionManager.activeSubscriptionInfoList.find { ... } (the calls in the
methods using the expression subscriptionManager.activeSubscriptionInfoList.find
— e.g., the functions that retrieve the SIM number by simSlotIndex) to use a
safe-call before .find (subscriptionManager.activeSubscriptionInfoList?.find {
... }) and propagate the nullable result (keep the existing ?.number?.takeIf {
it.isNotBlank() } logic) so you don't dereference a null list; apply the same
safe-call fix to the other occurrences mentioned (the calls at the earlier
methods and the one at line 115).

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/MessageEventPayload.kt`:
- Around line 9-10: The deprecated phoneNumber constructor property on
MessageEventPayload creates a nullability mismatch and allows callers to pass a
divergent value; change phoneNumber from a primary-constructor val into a body
property that delegates to sender and recipient to enforce the invariant (e.g.
annotate phoneNumber with `@Deprecated` and implement it as val phoneNumber:
String? get() = sender ?: recipient, or if downstream requires non-null use
get() = sender ?: recipient ?: ""), or use a backing field initialized to sender
?: recipient if your serializer needs a concrete field; update the
MessageEventPayload declaration to remove phoneNumber from the constructor and
implement the computed/delegated property so sender/recipient remain the single
source of truth.

---

Duplicate comments:
In `@app/src/main/java/me/capcom/smsgateway/helpers/SubscriptionsHelper.kt`:
- Around line 97-103: The code accesses the deprecated SubscriptionInfo.number
(on subscriptionManager.activeSubscriptionInfoList) which triggers a compiler
warning on API 33+; update getSimPhoneNumber to either suppress the deprecation
or preferably branch by API level: for API 33+ call
SubscriptionManager.getPhoneNumber(subscriptionId) after confirming
READ_PHONE_NUMBERS permission (extend or add to hasPhoneStatePermission), and
for older APIs continue using SubscriptionInfo.number; if you only want to
silence the warning immediately, add `@Suppress`("DEPRECATION") to the function
containing the use of SubscriptionInfo.number (referencing getSimPhoneNumber /
subscriptionManager.activeSubscriptionInfoList / simSlotIndex /
hasPhoneStatePermission).

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
app/src/main/assets/api/swagger.json (2)

2207-2209: Inconsistent naming: WebHookEvent vs smsgateway.WebhookEvent.

The existing event-type enum is named smsgateway.WebhookEvent (lowercase 'h'), while this callback schema is named WebHookEvent (uppercase 'H') and drops the smsgateway. prefix. The casing mismatch (Webhook vs WebHook) is likely to confuse SDK generators and API consumers. Consider aligning casing and prefix convention.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/assets/api/swagger.json` around lines 2207 - 2209, The schema
name WebHookEvent is inconsistent with the existing event-type
smsgateway.WebhookEvent (difference in casing and missing namespace); rename the
schema to match the existing identifier (smsgateway.WebhookEvent with the same
camelCasing "WebhookEvent" used elsewhere) and update any references in
swagger.json to use smsgateway.WebhookEvent so SDK generators and consumers see
a single canonical type name; ensure both the schema key and any $ref strings
are updated to the exact same identifier.

1436-1447: Static analysis: basic auth scheme over potentially unencrypted channel.

Checkov flags ApiAuth (HTTP basic) as allowing cleartext credentials when the local server ("url": "/") may run over plain HTTP. All endpoints already carry operation-level security, so the "no global security" warnings (CKV_OPENAPI_4/5) are effectively false positives here. However, for the basic auth concern, consider documenting that the local server is expected to be on a trusted network, or adding a note in the description.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/assets/api/swagger.json` around lines 1436 - 1447, Add guidance
to the ApiAuth security scheme to address Checkov's cleartext-credentials
warning: update the ApiAuth entry (in swagger.json) to include a descriptive
"description" that explicitly states this basic auth is intended only for
local/trusted-network use or must be used over HTTPS, or remove/replace ApiAuth
if you don't need basic auth; keep the JWTAuth entry unchanged. Ensure the
description references ApiAuth and documents the expected transport security
(trusted network or TLS) so static analysis clearly understands the constraint.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 2281-2309: Mark the phoneNumber property as deprecated and make
sender explicitly nullable: in the SmsEventPayload schema add "deprecated": true
to the phoneNumber property so code generators surface migration guidance, and
add "nullable": true to the sender property (matching destination) while keeping
its description that it may be null.
- Line 13: Update the license URL in the Swagger JSON: locate the licenses "url"
property (the entry currently set to
"http://www.apache.org/licenses/LICENSE-2.0") and change it to use HTTPS by
setting it to "https://www.apache.org/licenses/LICENSE-2.0" so the canonical
Apache 2.0 license link is secure.
- Around line 2222-2254: The WebHookEvent.event enum is missing two values
referenced elsewhere; update the WebHookEvent schema's "event" enum (symbol:
WebHookEvent.event) to include "mms:received" and "sms:data-received" so it
matches the referenced payloads (SmsDataReceivedPayload and any mms payload
handling), ensuring the enum contains
["sms:received","sms:sent","system:ping","sms:delivered","sms:failed","mms:received","sms:data-received"]
(or the equivalent order you prefer) to keep the swagger callback schema
consistent with the oneOf payload references.
- Around line 2233-2254: The payload "oneOf" array is missing the
MmsReceivedPayload reference, so update the payload schema's oneOf (the
"payload" entry) to include a reference to the MmsReceivedPayload schema (i.e.,
add a $ref to "#/components/schemas/MmsReceivedPayload") so that
WebhookEvent.event entries like "mms:received" can be validated and
deserialized.

---

Nitpick comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 2207-2209: The schema name WebHookEvent is inconsistent with the
existing event-type smsgateway.WebhookEvent (difference in casing and missing
namespace); rename the schema to match the existing identifier
(smsgateway.WebhookEvent with the same camelCasing "WebhookEvent" used
elsewhere) and update any references in swagger.json to use
smsgateway.WebhookEvent so SDK generators and consumers see a single canonical
type name; ensure both the schema key and any $ref strings are updated to the
exact same identifier.
- Around line 1436-1447: Add guidance to the ApiAuth security scheme to address
Checkov's cleartext-credentials warning: update the ApiAuth entry (in
swagger.json) to include a descriptive "description" that explicitly states this
basic auth is intended only for local/trusted-network use or must be used over
HTTPS, or remove/replace ApiAuth if you don't need basic auth; keep the JWTAuth
entry unchanged. Ensure the description references ApiAuth and documents the
expected transport security (trusted network or TLS) so static analysis clearly
understands the constraint.

Comment thread app/src/main/assets/api/swagger.json Outdated
Comment thread app/src/main/assets/api/swagger.json Outdated
Comment thread app/src/main/assets/api/swagger.json Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/assets/api/swagger.json (1)

1264-1272: ⚠️ Potential issue | 🟡 Minor

204 response MUST NOT define a response body.

Per RFC 9110 §15.3.5, a 204 response carries no content. Defining a content schema here is a spec violation and may cause code generators to emit dead deserialization logic. The other 204 responses in this file (e.g., /auth/token/{jti} DELETE at line 130 and /devices/{id} DELETE at line 266) correctly omit content.

🐛 Proposed fix
           "204": {
-            "description": "Webhook deleted",
-            "content": {
-              "application/json": {
-                "schema": {
-                  "type": "object"
-                }
-              }
-            }
+            "description": "Webhook deleted"
           },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/assets/api/swagger.json` around lines 1264 - 1272, The 204
response for the "Webhook deleted" operation incorrectly defines a response
body; remove the entire "content" object (and its nested "application/json" and
"schema") from the 204 response so the response only contains "description":
"Webhook deleted". Locate the 204 response block in the swagger.json that
contains "Webhook deleted" and update it to match other DELETE 204 responses
(e.g., the `/auth/token/{jti}` DELETE), ensuring no content/schema is present.
🧹 Nitpick comments (1)
app/src/main/assets/api/swagger.json (1)

2222-2232: WebHookEvent.event inline enum duplicates smsgateway.WebhookEvent; use a $ref instead.

The inline enum at lines 2224-2232 repeats the same seven values already defined in smsgateway.WebhookEvent (lines 2197-2205). Any future addition to the webhook event type must be added in two places.

♻️ Proposed refactor
           "event": {
-            "type": "string",
-            "enum": [
-              "sms:received",
-              "sms:sent",
-              "system:ping",
-              "sms:delivered",
-              "sms:failed",
-              "mms:received",
-              "sms:data-received"
-            ],
-            "description": "The type of event that triggered the webhook."
+            "description": "The type of event that triggered the webhook.",
+            "allOf": [
+              { "$ref": "#/components/schemas/smsgateway.WebhookEvent" }
+            ]
           },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/assets/api/swagger.json` around lines 2222 - 2232, Replace the
inline enum under the WebHookEvent.event property with a $ref to the existing
smsgateway.WebhookEvent schema so the event values are defined in one place;
locate the WebHookEvent definition (property "event") in swagger.json and change
the inline "type":"string" + "enum":[...] to a single "$ref":
"#/components/schemas/smsgateway.WebhookEvent" (or equivalent components path
used in this file), ensuring the schema now points to smsgateway.WebhookEvent
instead of duplicating the enum.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 1437-1439: The ApiAuth HTTP Basic scheme transmits credentials
unencrypted; update the OpenAPI entry for "ApiAuth" in swagger.json to warn
consumers and require secure transport: add a clear "description" on the
"ApiAuth" scheme stating that Basic auth MUST only be used over TLS, and either
change the local server entry (the server with "url": "/") to an HTTPS host or
add an explicit server-level or scheme-level note (e.g., description or vendor
extension) that the endpoint is local-only and must be accessed over a
trusted/encrypted channel; reference the "ApiAuth" object and the server with
"url": "/" when making these edits.
- Around line 2235-2259: The oneOf on WebHookEvent.payload is ambiguous because
payload variants (SmsReceivedPayload, SmsSentPayload, SmsDeliveredPayload,
SmsFailedPayload, SystemPingPayload, SmsDataReceivedPayload, MmsReceivedPayload)
lack discriminating required fields and there is no discriminator; update the
OpenAPI spec by adding a discriminator to WebHookEvent.payload with propertyName
"event" and a mapping for each variant to its schema, and also ensure each
payload schema includes a required "event" property (and where applicable a
unique required field like "message"/"receivedAt"/"sentAt") or add those unique
required fields in their inner allOf so each oneOf branch can be matched
exclusively.
- Around line 2404-2437: Add a "title" and "description" to the
MmsReceivedPayload schema to match other payloads (e.g., SmsReceivedPayload and
SmsSentPayload); update the schema object that references SmsEventPayload
(symbol: MmsReceivedPayload) by inserting a title like "MmsReceivedPayload" and
a concise description such as "Payload for received MMS messages" alongside the
existing properties so generated docs include the same metadata as other payload
schemas.
- Around line 2207-2261: The WebHookEvent schema is missing a required array and
is not using the project namespace; update the schema named "WebHookEvent" to
"smsgateway.WebHookEvent" (and similarly rename payload schemas
SmsReceivedPayload, SmsSentPayload, SmsDeliveredPayload, SmsFailedPayload,
SystemPingPayload, SmsDataReceivedPayload, MmsReceivedPayload to the
smsgateway.* equivalents) and add a required array that at minimum includes
"event" and "payload" (optionally include "id", "webhookId", "deviceId" if they
must be present); also update all $ref references across the spec to point to
the new smsgateway.* schema names so consumers and code generators use the
namespaced schemas.

---

Outside diff comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 1264-1272: The 204 response for the "Webhook deleted" operation
incorrectly defines a response body; remove the entire "content" object (and its
nested "application/json" and "schema") from the 204 response so the response
only contains "description": "Webhook deleted". Locate the 204 response block in
the swagger.json that contains "Webhook deleted" and update it to match other
DELETE 204 responses (e.g., the `/auth/token/{jti}` DELETE), ensuring no
content/schema is present.

---

Duplicate comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 2295-2313: The schema for the SMS message object needs two small
fixes: add "deprecated": true to the phoneNumber property and add "nullable":
true to the sender property so its description matches the schema (destination
already has nullable). Locate the object containing "phoneNumber", "sender",
"destination", "simNumber" in swagger.json and update phoneNumber to include
"deprecated": true and update sender to include "nullable": true (ensure valid
JSON with commas in the surrounding properties).

---

Nitpick comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 2222-2232: Replace the inline enum under the WebHookEvent.event
property with a $ref to the existing smsgateway.WebhookEvent schema so the event
values are defined in one place; locate the WebHookEvent definition (property
"event") in swagger.json and change the inline "type":"string" + "enum":[...] to
a single "$ref": "#/components/schemas/smsgateway.WebhookEvent" (or equivalent
components path used in this file), ensuring the schema now points to
smsgateway.WebhookEvent instead of duplicating the enum.

Comment thread app/src/main/assets/api/swagger.json Outdated
Comment thread app/src/main/assets/api/swagger.json Outdated
Comment thread app/src/main/assets/api/swagger.json Outdated
Comment thread app/src/main/assets/api/swagger.json Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 2387-2390: The SmsDataReceivedPayload.data schema lacks OpenAPI
annotations for base64 content; update the SmsDataReceivedPayload definition to
add format: byte and the same base64 validation pattern used by
smsgateway.DataMessage.data (use the identical pattern and the format: byte) so
generators validate/encode it consistently; locate SmsDataReceivedPayload.data
and mirror the annotation/pattern from smsgateway.DataMessage.data.

---

Duplicate comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 1220-1221: The referenced schemas and callback $ref use
inconsistent naming—update all schema names and $ref occurrences to include the
smsgateway. namespace so they match the rest of the file: rename/alias the
definitions for WebHookEvent, SmsEventPayload, SmsReceivedPayload,
SmsSentPayload, SmsDeliveredPayload, SmsFailedPayload, SystemPingPayload,
SmsDataReceivedPayload, and MmsReceivedPayload to smsgateway.WebHookEvent,
smsgateway.SmsEventPayload, etc., and update the callback $ref that points to
WebHookEvent to use "#/components/schemas/smsgateway.WebHookEvent"; ensure all
other references in the file are updated to the new names to avoid broken $ref
links.
- Around line 2282-2310: The SmsEventPayload schema still has inconsistencies:
mark the phoneNumber property as deprecated by adding "deprecated": true and
mark the sender property as nullable by adding "nullable": true; update the
SmsEventPayload object's properties (phoneNumber and sender) so phoneNumber is
explicitly deprecated and sender allows null to match its description.
- Around line 1430-1432: The ApiAuth security scheme (ApiAuth) currently uses
HTTP Basic (type: http, scheme: basic) without guidance; update the swagger.json
ApiAuth entry to include a clear description field stating that HTTP Basic MUST
only be used over TLS (HTTPS) or a trusted local channel and warning about
cleartext credentials, and ensure any references to ApiAuth in security
requirements remain unchanged; keep the description concise and explicit about
TLS requirement and recommended alternatives (e.g., token-based auth) for
external usage.
- Around line 2224-2248: The oneOf payload is ambiguous because variants like
SystemPingPayload are empty and none define an exclusive required discriminator
property; update the parent "payload" schema to include a discriminator (e.g.,
"discriminator": {"propertyName":"type", "mapping":{...}}) and then add a unique
required field (or a shared "type" enum) to each variant schema
(SmsReceivedPayload, SmsSentPayload, SmsDeliveredPayload, SmsFailedPayload,
SystemPingPayload, SmsDataReceivedPayload, MmsReceivedPayload) so validators can
select a single branch — for example add required
["type","message","receivedAt"] for SmsReceivedPayload (or at minimum a required
"type" with a unique value per schema) and ensure the discriminator mapping
points each discriminator value to the corresponding component schema.

Comment thread app/src/main/assets/api/swagger.json Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
app/src/main/assets/api/swagger.json (2)

1308-1400: Add explicit security: [] to health probe endpoints to signal intentional open access.

Omitting security is valid, but adding security: [] documents the intent and silences the Checkov CKV_OPENAPI_5 finding. The same applies to /health (line 330).

♻️ Example for `/health/live` (apply the same to `/health/ready`, `/health/startup`, and `/health`)
         "responses": { ... }
+        "security": []
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/assets/api/swagger.json` around lines 1308 - 1400, Add an
explicit empty security requirement to the health endpoints so they document
intentional open access and satisfy Checkov: for the GET operations under the
paths "/health/live", "/health/ready", "/health/startup" (and the "/health"
endpoint referenced in the comment) add a top-level "security: []" entry inside
each operation object (the same level as "tags", "summary", "description", and
"responses") so the spec clearly indicates these probes require no
authentication.

1434-1439: JWTAuth should use type: http / scheme: bearer instead of apiKey.

Using type: apiKey with name: Authorization to represent a Bearer token is a Swagger 2.0 workaround. While it works, it is semantically incorrect as it uses the API key model to represent a Bearer token — a hacky solution from the past. OpenAPI 3.0 has native support for this.

♻️ Proposed fix
       "JWTAuth": {
-        "type": "apiKey",
-        "description": "JWT authentication",
-        "name": "Authorization",
-        "in": "header"
+        "type": "http",
+        "scheme": "bearer",
+        "bearerFormat": "JWT",
+        "description": "JWT Bearer authentication"
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/assets/api/swagger.json` around lines 1434 - 1439, Replace the
JWTAuth security scheme definition so it uses the OpenAPI HTTP Bearer scheme
instead of an apiKey: locate the "JWTAuth" object in swagger.json and change its
fields from "type": "apiKey", "name": "Authorization", "in": "header" to "type":
"http" and "scheme": "bearer" (optionally add "bearerFormat": "JWT") so the
security scheme is semantically correct for bearer tokens.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 2304-2308: The Swagger schema for SmsEventPayload.simNumber is
missing the numeric range; update the simNumber property (same field represented
as smsgateway.Message.simNumber elsewhere) to include "minimum" and "maximum"
constraints matching the documented range (e.g., add "minimum": 0 and "maximum":
3), keep "type": "integer" and "nullable": true, and ensure the description
remains intact so consumers know expected values.
- Around line 1469-1471: The OpenAPI property "expires_at" is defined as type
"string" but missing the "format: date-time", causing generators to produce a
plain string instead of a datetime; update the "expires_at" schema in
swagger.json to include "format": "date-time" alongside "type": "string" (look
for the "expires_at" property in the JSON and add the format field) so codegen
emits a proper datetime type.

---

Duplicate comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 1430-1432: The ApiAuth security scheme currently declares "type":
"http" and "scheme": "basic" which transmits credentials in cleartext over
non-TLS connections; update the ApiAuth object in swagger.json to include a
descriptive warning (e.g., a "description" property on ApiAuth) stating that
HTTP Basic must only be used over TLS (HTTPS) and recommend using stronger
alternatives (Bearer tokens/OAuth) or ensuring TLS is enforced; locate the
ApiAuth entry by the "ApiAuth" key to make this change.
- Around line 2291-2297: Update the OpenAPI schema entries for the properties
"phoneNumber" and "sender" in swagger.json: mark "phoneNumber" with
"deprecated": true to indicate migration to "sender"/"destination", and add
"nullable": true to the "sender" property so its schema matches the description
that it may be null (same behavior as "destination"). Ensure the keys are added
at the same object level as "type" and "description" for each property.
- Around line 2200-2258: The WebHookEvent schema and its payload variants must
be namespaced and discriminable: change the schema name and all refs to use the
project namespace (e.g., smsgateway.WebHookEvent, smsgateway.SmsReceivedPayload,
smsgateway.SmsSentPayload, etc.), then replace the bare oneOf for
WebHookEvent.payload with a discriminator object (e.g., "discriminator": {
"propertyName": "type", "mapping": {
"sms_received":"#/components/schemas/smsgateway.SmsReceivedPayload", ... } })
and ensure each payload schema declares the discriminator property (type) as a
required field with a constant/enum value unique per variant so validators can
unambiguously select the correct schema (update SmsReceivedPayload,
SmsSentPayload, SmsDeliveredPayload, SmsFailedPayload, SystemPingPayload,
SmsDataReceivedPayload, MmsReceivedPayload accordingly).

---

Nitpick comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 1308-1400: Add an explicit empty security requirement to the
health endpoints so they document intentional open access and satisfy Checkov:
for the GET operations under the paths "/health/live", "/health/ready",
"/health/startup" (and the "/health" endpoint referenced in the comment) add a
top-level "security: []" entry inside each operation object (the same level as
"tags", "summary", "description", and "responses") so the spec clearly indicates
these probes require no authentication.
- Around line 1434-1439: Replace the JWTAuth security scheme definition so it
uses the OpenAPI HTTP Bearer scheme instead of an apiKey: locate the "JWTAuth"
object in swagger.json and change its fields from "type": "apiKey", "name":
"Authorization", "in": "header" to "type": "http" and "scheme": "bearer"
(optionally add "bearerFormat": "JWT") so the security scheme is semantically
correct for bearer tokens.

Comment thread app/src/main/assets/api/swagger.json Outdated
Comment thread app/src/main/assets/api/swagger.json Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 1620-1623: The OpenAPI schema for smsgateway.LogEntry.createdAt is
missing the format annotation so generators produce a plain string; update the
LogEntry schema to add "format: date-time" to the createdAt property (matching
the other timestamp fields like SmsReceivedPayload.receivedAt and
SmsSentPayload.sentAt) so codegens emit a proper datetime type and ensure the
description/documentation remains unchanged.

---

Duplicate comments:
In `@app/src/main/assets/api/swagger.json`:
- Around line 1434-1437: The ApiAuth scheme in swagger.json currently uses
"type": "http" and "scheme": "basic" with no advisory; update the ApiAuth
definition to include a clear description field that warns basic auth transmits
base64-encoded credentials and MUST only be used over TLS (HTTPS) — reference
the "ApiAuth" object and its "scheme": "basic" entry and add the description
text to that object so consumers and scanners are alerted to the TLS
requirement.
- Around line 2295-2312: Update the SmsEventPayload schema: mark the phoneNumber
property as "deprecated": true; add "nullable": true to the sender property (to
match destination) and update its description if needed; and add "minimum": 1
and "maximum": 3 to the simNumber integer property (which is already nullable)
so it matches smsgateway.Message.simNumber. Reference the SmsEventPayload schema
and the properties phoneNumber, sender, destination, and simNumber when making
these edits.
- Around line 2204-2261: The WebHookEvent schema and its payload variants are
using non-namespaced names and the payload oneOf lacks a discriminator which
will break validators; rename WebHookEvent and each payload schema to use the
smsgateway. prefix (e.g., smsgateway.WebHookEvent,
smsgateway.SmsReceivedPayload, smsgateway.SmsSentPayload, etc.) and update the
$ref targets accordingly, and then add a discriminator for the payload oneOf
that uses the outer "event" field (add a discriminator object with propertyName
"event" and mapping entries for each smsgateway.* payload) or alternatively add
unique required fields inside each payload's allOf to guarantee exactly one
branch matches; update the WebHookEvent.schema so "event" remains the
discriminant and the payload oneOf references the namespaced schemas.

Comment thread app/src/main/assets/api/swagger.json Outdated
@capcom6 capcom6 force-pushed the webhooks/sms-received-destination-number branch from 3762198 to 0bb0840 Compare February 23, 2026 00:31
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt (1)

69-84: simNumber ?: 0 masks "unknown SIM" for SMS payloads that accept Int?.

SmsEventPayload.SmsReceived and SmsEventPayload.SmsDataReceived declare simNumber: Int?, so they can carry null to represent an unknown SIM. Defaulting to 0 conflates "unknown" with a potentially valid value. Only MmsReceivedPayload requires non-null Int.

Consider passing simNumber (nullable) for SMS payloads and reserving the ?: 0 fallback for MMS only:

♻️ Proposed fix
             is InboxMessage.Text -> WebHookEvent.SmsReceived to SmsEventPayload.SmsReceived(
                 messageId = message.hashCode().toUInt().toString(16),
                 message = message.text,
                 sender = sender,
-                simNumber = simNumber ?: 0,
+                simNumber = simNumber,
                 receivedAt = message.date,
                 recipient = recipient,
             )

             is InboxMessage.Data -> WebHookEvent.SmsDataReceived to SmsEventPayload.SmsDataReceived(
                 messageId = message.hashCode().toUInt().toString(16),
                 data = Base64.encodeToString(message.data, Base64.NO_WRAP),
-                simNumber = simNumber ?: 0,
+                simNumber = simNumber,
                 receivedAt = message.date,
                 sender = sender,
                 recipient = recipient,
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt`
around lines 69 - 84, In the message handling branch, don't coerce simNumber to
0 for SMS payloads—pass the nullable simNumber directly to
SmsEventPayload.SmsReceived and SmsEventPayload.SmsDataReceived so null
represents "unknown SIM"; keep the existing simNumber ?: 0 fallback only when
constructing MmsReceivedPayload (which requires a non-null Int). Locate the
simNumber variable and the when branch creating SmsEventPayload.SmsReceived,
SmsEventPayload.SmsDataReceived and MmsReceivedPayload and change the SMS
payloads to use simNumber (nullable) while leaving the MMS construction
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@app/src/main/java/me/capcom/smsgateway/helpers/SubscriptionsHelper.kt`:
- Around line 88-104: getPhoneNumber currently uses the deprecated
SubscriptionInfo.number (deprecated in API 33); update getPhoneNumber (and the
other sibling methods in this file) to avoid calling SubscriptionInfo.number
directly by using the newer API when available: for API >= 33 call
SubscriptionManager.getPhoneNumber(subscriptionId) (or the appropriate
non-deprecated Telephony/SubscriptionManager API) using the
SubscriptionInfo.subscriptionId, and for older APIs fall back to
SubscriptionInfo.number with proper null/blank checks; ensure calls are guarded
by SDK checks and preserve the existing permission and null-safety logic in
getPhoneNumber and related methods.

In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/payload/MessageEventPayload.kt`:
- Around line 3-11: The constructor currently declares phoneNumber as an
independent non-null val which can diverge from sender/recipient; remove
phoneNumber from the constructor parameters in the MessageEventPayload class and
instead add a body property val phoneNumber: String = sender ?: recipient ?: ""
(retain the `@Deprecated` annotation on the property if desired) so the invariant
is enforced at construction time and the nullability gap is eliminated; update
any subclasses/callers that passed phoneNumber to stop providing it and rely on
the new derived property.

---

Nitpick comments:
In `@app/src/main/java/me/capcom/smsgateway/modules/receiver/ReceiverService.kt`:
- Around line 69-84: In the message handling branch, don't coerce simNumber to 0
for SMS payloads—pass the nullable simNumber directly to
SmsEventPayload.SmsReceived and SmsEventPayload.SmsDataReceived so null
represents "unknown SIM"; keep the existing simNumber ?: 0 fallback only when
constructing MmsReceivedPayload (which requires a non-null Int). Locate the
simNumber variable and the when branch creating SmsEventPayload.SmsReceived,
SmsEventPayload.SmsDataReceived and MmsReceivedPayload and change the SMS
payloads to use simNumber (nullable) while leaving the MMS construction
unchanged.

@capcom6 capcom6 force-pushed the webhooks/sms-received-destination-number branch from 73ff296 to dfb3cd8 Compare February 25, 2026 07:34
@capcom6 capcom6 marked this pull request as ready for review February 26, 2026 01:53
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 26, 2026

🤖 Pull request artifacts

file commit
app-release.apk b2d7709
app-release.aab b2d7709
app-insecure.apk b2d7709
app-insecure.aab b2d7709

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dfb3cd8d68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/main/assets/api/swagger.json Outdated
@capcom6 capcom6 force-pushed the webhooks/sms-received-destination-number branch from 1c76f82 to b2d7709 Compare February 27, 2026 00:53
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@capcom6 capcom6 merged commit a90d611 into master Feb 28, 2026
3 checks passed
@capcom6 capcom6 deleted the webhooks/sms-received-destination-number branch February 28, 2026 00:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant