mirror of
https://github.com/layer-systems/website.git
synced 2026-09-13 06:07:29 +02:00
fix: reject non-integer/negative spell kinds, de-flake a timing test
Per remaining "previously missed" findings: - parseSpell() now requires k tags to be non-negative integers (Number.isInteger && >= 0), not just finite — a relay-sourced spell claiming kind "1.5" or "-1" no longer passes through into a malformed filter. - The resolveTimestamp wall-clock tests asserted toBeCloseTo a single captured `now`, which a slow runner or timing skew between the two Date.now() calls could flake. Replaced with a before/after range assertion. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYiUtZMQeA5RHggQw73wto
This commit is contained in:
@@ -27,13 +27,22 @@ function parsedSpell(overrides: Partial<ParsedSpell>): ParsedSpell {
|
||||
|
||||
describe('resolveTimestamp', () => {
|
||||
it('resolves a relative duration against now', () => {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
expect(resolveTimestamp('7d')).toBeCloseTo(now - 7 * 86400, -1);
|
||||
const before = Math.floor(Date.now() / 1000) - 7 * 86400;
|
||||
const result = resolveTimestamp('7d');
|
||||
const after = Math.floor(Date.now() / 1000) - 7 * 86400;
|
||||
// A range, not toBeCloseTo against a single captured `now` — a slow test
|
||||
// runner or wall-clock skew between the two Date.now() calls could
|
||||
// otherwise make this flaky.
|
||||
expect(result).toBeGreaterThanOrEqual(before);
|
||||
expect(result).toBeLessThanOrEqual(after);
|
||||
});
|
||||
|
||||
it('resolves "now"', () => {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
expect(resolveTimestamp('now')).toBeCloseTo(now, -1);
|
||||
const before = Math.floor(Date.now() / 1000);
|
||||
const result = resolveTimestamp('now');
|
||||
const after = Math.floor(Date.now() / 1000);
|
||||
expect(result).toBeGreaterThanOrEqual(before);
|
||||
expect(result).toBeLessThanOrEqual(after);
|
||||
});
|
||||
|
||||
it('resolves an absolute unix timestamp', () => {
|
||||
@@ -88,6 +97,19 @@ describe('encodeSpellTags / parseSpell round-trip', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseSpell', () => {
|
||||
it('drops non-integer and negative k tags — kinds are non-negative integers', () => {
|
||||
const event = spellEvent([
|
||||
['cmd', 'REQ'],
|
||||
['k', '1'],
|
||||
['k', '1.5'],
|
||||
['k', '-1'],
|
||||
['k', 'not-a-number'],
|
||||
]);
|
||||
expect(parseSpell(event).kinds).toEqual([1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isValidTagLetter', () => {
|
||||
it('accepts a single letter', () => {
|
||||
expect(isValidTagLetter('t')).toBe(true);
|
||||
|
||||
@@ -107,7 +107,11 @@ export function encodeSpellTags(input: SpellInput): string[][] {
|
||||
}
|
||||
|
||||
export function parseSpell(event: NostrEvent): ParsedSpell {
|
||||
const kinds = tagValues(event, 'k').map(Number).filter((n) => Number.isFinite(n));
|
||||
// Nostr kinds are non-negative integers — a relay-sourced spell claiming
|
||||
// e.g. "1.5" or "-1" would otherwise pass through into a malformed filter.
|
||||
const kinds = tagValues(event, 'k')
|
||||
.map(Number)
|
||||
.filter((n) => Number.isInteger(n) && n >= 0);
|
||||
const authorsTag = event.tags.find(([name]) => name === 'authors');
|
||||
const tagFilterTag = event.tags.find(([name]) => name === 'tag');
|
||||
const limitValue = tagValue(event, 'limit');
|
||||
|
||||
Reference in New Issue
Block a user