@apitap/core 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/read/peek.ts CHANGED
@@ -48,6 +48,22 @@ export async function peek(url: string, options: PeekOptions = {}): Promise<Peek
48
48
  const contentType = headers['content-type'] || null;
49
49
  const server = headers['server'] || null;
50
50
 
51
+ // JSON API responses with HTTP 200 are always accessible, regardless of CDN headers
52
+ if (status === 200 && contentType && contentType.includes('application/json')) {
53
+ const framework = detectFramework(headers, signals);
54
+ return {
55
+ url,
56
+ status,
57
+ accessible: true,
58
+ contentType,
59
+ server,
60
+ framework,
61
+ botProtection: null,
62
+ signals,
63
+ recommendation: 'read',
64
+ };
65
+ }
66
+
51
67
  // Detect bot protection
52
68
  const botProtection = detectBotProtection(headers, signals);
53
69
 
@@ -628,7 +628,7 @@ export async function replayMultiple(
628
628
  const skillCache = new Map<string, SkillFile | null>();
629
629
  const uniqueDomains = [...new Set(requests.map(r => r.domain))];
630
630
  await Promise.all(uniqueDomains.map(async (domain) => {
631
- const skill = await readSkillFile(domain, options.skillsDir, { verifySignature: true, signingKey });
631
+ const skill = await readSkillFile(domain, options.skillsDir, { verifySignature: true, signingKey, trustUnsigned: true });
632
632
  skillCache.set(domain, skill);
633
633
  }));
634
634
 
@@ -85,7 +85,17 @@ export async function readSkillFile(
85
85
  }
86
86
  } else {
87
87
  const { verifySignature } = await import('./signing.js');
88
- if (!verifySignature(skill, signingKey)) {
88
+ let verified = verifySignature(skill, signingKey);
89
+ if (!verified) {
90
+ // Fallback: try pre-v1.4.0 legacy key (before HKDF signing key separation)
91
+ // Files signed with deriveKey() directly (not deriveSigningKey()) will match here
92
+ const { deriveKey } = await import('../auth/crypto.js');
93
+ const { getMachineId } = await import('../auth/manager.js');
94
+ const machineId = await getMachineId();
95
+ const legacyKey = deriveKey(machineId);
96
+ verified = verifySignature(skill, legacyKey);
97
+ }
98
+ if (!verified) {
89
99
  throw new Error(`Skill file signature verification failed for ${domain} — file may be tampered`);
90
100
  }
91
101
  }