tombstone-author.test.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. const { eq, ok, notOk } = require('../../helpers/assert');
  2. const { buildValidatedTombstoneSet } = require('../../../src/models/tombstone_validator');
  3. describe('tombstone validation: author check', (t) => {
  4. t('honors a tombstone whose author matches the target author', () => {
  5. const messages = [
  6. { key: '%alice-event.sha256', value: { author: '@alice.ed25519', timestamp: 1, content: { type: 'event', title: 'A' } } },
  7. { key: '%alice-tomb.sha256', value: { author: '@alice.ed25519', timestamp: 2, content: { type: 'tombstone', target: '%alice-event.sha256' } } }
  8. ];
  9. const tomb = buildValidatedTombstoneSet(messages);
  10. eq(tomb.size, 1);
  11. ok(tomb.has('%alice-event.sha256'));
  12. });
  13. t('ignores a tombstone whose author does NOT match the target author (Eve forgery)', () => {
  14. const messages = [
  15. { key: '%alice-event.sha256', value: { author: '@alice.ed25519', timestamp: 1, content: { type: 'event', title: 'A' } } },
  16. { key: '%eve-fake-tomb.sha256', value: { author: '@eve.ed25519', timestamp: 2, content: { type: 'tombstone', target: '%alice-event.sha256' } } }
  17. ];
  18. const tomb = buildValidatedTombstoneSet(messages);
  19. eq(tomb.size, 0, 'Eve\'s forged tombstone targeting Alice\'s event must be ignored');
  20. });
  21. t('latest tombstone wins when same author rebroadcasts', () => {
  22. const messages = [
  23. { key: '%post.sha256', value: { author: '@a.ed25519', timestamp: 1, content: { type: 'post', text: 'hi' } } },
  24. { key: '%t1.sha256', value: { author: '@a.ed25519', timestamp: 2, content: { type: 'tombstone', target: '%post.sha256' } } },
  25. { key: '%t2.sha256', value: { author: '@eve.ed25519', timestamp: 3, content: { type: 'tombstone', target: '%post.sha256' } } }
  26. ];
  27. const tomb = buildValidatedTombstoneSet(messages);
  28. notOk(tomb.has('%post.sha256'), 'Eve\'s later tombstone replaces in the claim map but is rejected at validation');
  29. });
  30. t('encrypted-tribe tombstone only honored when target was in the same tribe', () => {
  31. const messages = [
  32. { key: '%alice-public-msg.sha256', value: { author: '@alice.ed25519', timestamp: 1, content: { type: 'event', title: 'Public' } } },
  33. { key: '%tribe-msg.sha256', value: { author: '@bob.ed25519', timestamp: 2, content: { type: 'event', title: 'In tribe', _rootId: '%tribe.sha256' } } },
  34. { key: '%t-cross.sha256', value: { author: '@bob.ed25519', timestamp: 3, content: { type: 'tombstone', target: '%alice-public-msg.sha256', _rootId: '%tribe.sha256' } } },
  35. { key: '%t-same.sha256', value: { author: '@bob.ed25519', timestamp: 4, content: { type: 'tombstone', target: '%tribe-msg.sha256', _rootId: '%tribe.sha256' } } }
  36. ];
  37. const tomb = buildValidatedTombstoneSet(messages);
  38. notOk(tomb.has('%alice-public-msg.sha256'), 'tribe-flattened tombstone must not suppress unrelated public message');
  39. ok(tomb.has('%tribe-msg.sha256'), 'tribe-flattened tombstone honored when target lives in the same tribe');
  40. });
  41. t('returns empty set on malformed input', () => {
  42. eq(buildValidatedTombstoneSet(null).size, 0);
  43. eq(buildValidatedTombstoneSet(undefined).size, 0);
  44. eq(buildValidatedTombstoneSet([]).size, 0);
  45. eq(buildValidatedTombstoneSet([{ value: null }]).size, 0);
  46. });
  47. });