-
Notifications
You must be signed in to change notification settings - Fork 731
fix: security contacts ingestion improvements [CM-1297] #4295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
26facec
dc78313
f4405d7
647207b
829220c
1633ec2
04aad47
33d8376
8e4a6ea
b746e41
36ecfbd
8f3669f
a958c14
5c35e59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ALTER TABLE security_contacts ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { ExtractorDeps } from '../types' | ||
|
|
||
| /** null means unresolved (empty repo, truncated, fetch failure) — callers must fall back to probing. */ | ||
| export interface RepoTree { | ||
| paths: Set<string> | null | ||
| } | ||
|
|
||
| interface GitTreeEntry { | ||
| path?: unknown | ||
| type?: unknown | ||
| } | ||
|
|
||
| interface GitTreeResponse { | ||
| tree?: GitTreeEntry[] | ||
| truncated?: boolean | ||
| } | ||
|
|
||
| // `HEAD` resolves to the default branch on the git data API. | ||
| export async function fetchRepoTree( | ||
| owner: string, | ||
| name: string, | ||
| githubGet: ExtractorDeps['githubGet'], | ||
| ): Promise<RepoTree> { | ||
| try { | ||
| const { text } = await githubGet(`/repos/${owner}/${name}/git/trees/HEAD?recursive=1`) | ||
| if (!text) return { paths: null } | ||
|
|
||
| const doc = JSON.parse(text) as GitTreeResponse | ||
| if (doc.truncated || !Array.isArray(doc.tree)) return { paths: null } | ||
|
|
||
| const paths = new Set<string>() | ||
| for (const entry of doc.tree) { | ||
| if (entry.type === 'blob' && typeof entry.path === 'string') paths.add(entry.path) | ||
| } | ||
| return { paths } | ||
| } catch { | ||
| return { paths: null } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,8 @@ const GITHUB_API = 'https://api.github.com' | |
|
|
||
| // Genuinely-absent / not-determinable → null body (see http.ts for the same set). 422 covers the | ||
| // PVR endpoint returning "can't determine" per-repo; it must read as unknown, not a hard failure. | ||
| const ABSENT_STATUSES = new Set([404, 410, 422]) | ||
| // 451 (Unavailable For Legal Reasons) is likewise permanent. | ||
| const ABSENT_STATUSES = new Set([404, 410, 422, 451]) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 451 responses wipe stored contactsHigh Severity HTTP 451 was added to the absent-status set for GitHub and registry fetches, so those calls return empty bodies instead of failing. When every extractor therefore finishes successfully with no contacts, Additional Locations (1)Reviewed by Cursor Bugbot for commit b746e41. Configure here.
mbani01 marked this conversation as resolved.
|
||
|
|
||
| // App-wide ceiling on concurrent GitHub requests. GitHub's secondary limit rejects bursts of | ||
| // >100 concurrent requests from one app; staying under that (across all installations) is the | ||
|
|
||


Uh oh!
There was an error while loading. Please reload this page.