fix: API was updated to show ticket type so we can now filter receipts out
What changed, and why it matters
This commit updates the wallet's integration with a third-party shopping service. The service's API now labels certain records as 'receipts', and the wallet now skips those records when refreshing ticket data. This appears to be a correctness or data-handling fix rather than a security vulnerability. There is no indication it fixes an exploit or protects user funds directly.
No immediate security action required. Treat as a routine functional update. If reviewing for security, verify that skipping receipt records does not hide important transaction state or audit entries from users, and that the upstream `ticket_kind` value cannot be spoofed or manipulated by an attacker.
Security signals we found
No security-relevant keywords in commit title or message
Change is a data-filtering/correctness adjustment based on upstream API field
No validation, sanitization, or boundary checks added
No secrets, permissions, or cryptographic operations modified
Evidence from the diff
The patch adds a nullable kind field (parsed from JSON key ticket_kind) to the TicketRef model and a derived isKnownReceipt getter that returns true only when kind == 'receipt'. The refresh loop in ShopInBitService now filters out any ticket reference where isKnownReceipt is true before calling _refreshRef. The commit message frames this as a functional fix enabled by an upstream API change. No input validation, authentication, cryptographic, or access-control changes are present.
Changed components
lib/services/shopinbit/shopinbit_service.dartlib/services/shopinbit/src/models/ticket.dartInspect captured patch +19 / −4
diff --git a/lib/services/shopinbit/shopinbit_service.dart b/lib/services/shopinbit/shopinbit_service.dart
index b40c1b3..0c41d6a 100644
--- a/lib/services/shopinbit/shopinbit_service.dart
+++ b/lib/services/shopinbit/shopinbit_service.dart
@@ -67,7 +67,11 @@ class ShopInBitService {
);
return;
}
- await Future.wait(resp.value!.map((ref) => _refreshRef(ref, key)));
+ await Future.wait(
+ resp.value!
+ .where((e) => !e.isKnownReceipt)
+ .map((ref) => _refreshRef(ref, key)),
+ );
}
/// Refresh a single ticket. The row must already exist; use this for
diff --git a/lib/services/shopinbit/src/models/ticket.dart b/lib/services/shopinbit/src/models/ticket.dart
index 0a3a386..df898b6 100644
--- a/lib/services/shopinbit/src/models/ticket.dart
+++ b/lib/services/shopinbit/src/models/ticket.dart
@@ -44,14 +44,25 @@ class TicketRef {
final int id;
final String number;
- TicketRef({required this.id, required this.number});
+ /// [kind] is nullable for backwards compat only
+ final String? kind;
+
+ /// True only when [kind] explicitly marks this as a receipt ticket.
+ /// False does not rule it out, since legacy tickets have a null [kind].
+ bool get isKnownReceipt => kind == "receipt";
+
+ TicketRef({required this.id, required this.number, this.kind});
factory TicketRef.fromJson(Map<String, dynamic> json) {
- return TicketRef(id: _toInt(json['id']), number: json['number'] as String);
+ return TicketRef(
+ id: _toInt(json['id']),
+ number: json['number'] as String,
+ kind: json['ticket_kind'] as String?,
+ );
}
Map<String, dynamic> toMap() {
- return {"id": id, "number": number};
+ return {"id": id, "number": number, "kind": kind};
}
@override
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.