a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(lexicon-doc): verify external references have valid NSID

Mary 1ed09c9a 6a589c0c

+61 -2
+5
.changeset/tough-sides-relate.md
··· 1 + --- 2 + '@atcute/lexicon-doc': patch 3 + --- 4 + 5 + verify external references have valid NSID
+45
packages/lexicons/lexicon-doc/lib/utils/refs.test.ts
··· 552 552 expect(refs.size).toBe(0); 553 553 }); 554 554 555 + it('skips refs with invalid NSIDs', () => { 556 + const doc: LexiconDoc = { 557 + lexicon: 1, 558 + id: 'com.example.test', 559 + defs: { 560 + main: { 561 + type: 'object', 562 + properties: { 563 + bad1: { type: 'ref', ref: 'not-an-nsid#main' }, 564 + bad2: { type: 'ref', ref: 'garbage' }, 565 + bad3: { type: 'ref', ref: 'lex:at.inlay.defs#main' }, 566 + good: { type: 'ref', ref: 'com.example.valid#main' }, 567 + }, 568 + }, 569 + }, 570 + }; 571 + 572 + const refs = findExternalReferences(doc); 573 + expect(refs.size).toBe(1); 574 + expect(refs.has('com.example.valid#main')).toBe(true); 575 + }); 576 + 577 + it('skips union refs with invalid NSIDs', () => { 578 + const doc: LexiconDoc = { 579 + lexicon: 1, 580 + id: 'com.example.test', 581 + defs: { 582 + main: { 583 + type: 'object', 584 + properties: { 585 + item: { 586 + type: 'union', 587 + refs: ['invalid', 'also-invalid#foo', 'lex:at.inlay.defs#main', 'com.example.valid#main'], 588 + closed: false, 589 + }, 590 + }, 591 + }, 592 + }, 593 + }; 594 + 595 + const refs = findExternalReferences(doc); 596 + expect(refs.size).toBe(1); 597 + expect(refs.has('com.example.valid#main')).toBe(true); 598 + }); 599 + 555 600 it('handles non-existent defId parameter', () => { 556 601 const doc: LexiconDoc = { 557 602 lexicon: 1,
+11 -2
packages/lexicons/lexicon-doc/lib/utils/refs.ts
··· 92 92 case 'ref': { 93 93 const id = getInternalDefId(def.ref, doc.id); 94 94 if (id === undefined) { 95 - refs.add(def.ref); 95 + if (isValidExternalRef(def.ref)) { 96 + refs.add(def.ref); 97 + } 96 98 break; 97 99 } 98 100 ··· 114 116 const ref = def.refs[idx]; 115 117 const id = getInternalDefId(ref, doc.id); 116 118 if (id === undefined) { 117 - refs.add(ref); 119 + if (isValidExternalRef(ref)) { 120 + refs.add(ref); 121 + } 118 122 continue; 119 123 } 120 124 ··· 181 185 } 182 186 183 187 return refs; 188 + }; 189 + 190 + const isValidExternalRef = (ref: string): boolean => { 191 + const hashIndex = ref.indexOf('#'); 192 + return isNsid(hashIndex === -1 ? ref : ref.slice(0, hashIndex)); 184 193 }; 185 194 186 195 const getInternalDefId = (ref: string, docId: string): string | undefined => {