fix(mobile): reject stale destination membership fallback

Signed-off-by: Logan Johnson <loganj@squareup.com>
This commit is contained in:
Logan Johnson
2026-09-05 17:42:31 -04:00
parent b0a476930a
commit 882f69cbaf
2 changed files with 16 additions and 5 deletions

View File

@@ -46,9 +46,7 @@ Future<List<AgentDirectoryEntry>> readAgentAuthorization(
check();
final latest = <String, NostrEvent>{};
for (final event in membership) {
if (event.kind != 39002 ||
event.pubkey != authority ||
!verifySignedEvent(event)) {
if (event.kind != 39002 || event.pubkey != authority) {
continue;
}
final destination = event.getTagValue('d');
@@ -66,6 +64,13 @@ Future<List<AgentDirectoryEntry>> readAgentAuthorization(
final owned = agent.ownerPubkey == viewer;
final channels = <String>[];
for (final entry in latest.entries) {
if (!verifySignedEvent(entry.value) ||
entry.value.tags
.where((tag) => tag.isNotEmpty && tag[0] == 'd')
.length !=
1) {
continue;
}
final people = entry.value.tags.where(
(tag) => tag.length >= 2 && tag[0] == 'p',
);
@@ -109,7 +114,7 @@ Future<List<NostrEvent>> _membershipPages(
kinds: const [39002],
authors: [authority],
tags: {
'#p': [viewer],
if (channelId == null) '#p': [viewer],
if (channelId != null) '#d': [channelId],
},
limit: 500,

View File

@@ -99,7 +99,6 @@ void main() {
final filter = session.queries.first;
expect(filter.authors, [relay.public]);
expect(filter.tags, {
'#p': [owner.public],
'#d': ['room'],
});
expect(
@@ -133,6 +132,13 @@ void main() {
NostrEvent.fromJson({...members().toJson(), 'content': 'tampered'}),
],
[members(), members(time: 101, includeAgent: false)],
[
members(),
NostrEvent.fromJson({
...members(time: 101).toJson(),
'content': 'tampered',
}),
],
[members(), members(time: 101, includeViewer: false)],
]) {
final result = await read(