Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE security_contacts ADD COLUMN IF NOT EXISTS reachable BOOLEAN NOT NULL DEFAULT TRUE;
Comment thread
mbani01 marked this conversation as resolved.
ALTER TABLE security_contacts ADD COLUMN IF NOT EXISTS reachability_reason TEXT;
Comment thread
cursor[bot] marked this conversation as resolved.
Comment on lines +1 to +2
Comment on lines +1 to +2
Comment on lines +1 to +2
Comment on lines +1 to +2
13 changes: 12 additions & 1 deletion services/apps/packages_worker/src/security-contacts/reconcile.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { classifyEmailReachability, type EmailReachabilityReason } from '@crowd/common'

Check failure on line 1 in services/apps/packages_worker/src/security-contacts/reconcile.ts

View workflow job for this annotation

GitHub Actions / lint-format-services

Replace `classifyEmailReachability,·type·EmailReachabilityReason` with `type·EmailReachabilityReason,·classifyEmailReachability`

import { scoreContact } from './score'
import {
ContactChannel,
Expand Down Expand Up @@ -56,6 +58,15 @@
return false
}

function classifyReachability(c: RawContact): {
reachable: boolean
reachabilityReason: EmailReachabilityReason | null
} {
if (c.channel !== 'email') return { reachable: true, reachabilityReason: null }
const r = classifyEmailReachability(c.value)
return { reachable: r.reachable, reachabilityReason: r.reason }
Comment on lines +65 to +67
}

function normalizeValue(channel: ContactChannel, value: string): string {
const v = value.trim()
return channel === 'email' || channel === 'github-handle' ? v.toLowerCase() : v
Expand Down Expand Up @@ -130,7 +141,7 @@

const scored: ScoredContact[] = merged.map((c) => {
const contact = { ...c, provenance: dedupeProvenance(c.provenance) }
return { ...contact, ...scoreContact(contact, now) }
return { ...contact, ...scoreContact(contact, now), ...classifyReachability(contact) }
Comment on lines 142 to +144
Comment on lines 142 to +144
Comment on lines 142 to +144
})

scored.sort(
Expand Down
3 changes: 3 additions & 0 deletions services/apps/packages_worker/src/security-contacts/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { EmailReachabilityReason } from '@crowd/common'
import type { SecurityContactConfidence } from '@crowd/data-access-layer/src/osspckgs/api'

export type ContactChannel = 'email' | 'github-pvr' | 'url' | 'github-handle' | 'web-form'
Expand Down Expand Up @@ -30,6 +31,8 @@ export interface RawContact {
export interface ScoredContact extends RawContact {
score: number
confidence: SecurityContactConfidence
reachable: boolean
reachabilityReason: EmailReachabilityReason | null
}

export interface RepoPolicies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,18 @@ export async function writeContacts(
await tx.result(
prepareBulkInsert(
'security_contacts',
['repo_id', 'channel', 'value', 'role', 'name', 'score', 'confidence', 'provenance'],
[
'repo_id',
'channel',
'value',
'role',
'name',
'score',
'confidence',
'provenance',
'reachable',
'reachability_reason',
],
contacts.map((c) => ({
repo_id: repoId,
channel: c.channel,
Expand All @@ -40,13 +51,17 @@ export async function writeContacts(
score: c.score,
confidence: c.confidence,
provenance: JSON.stringify(c.provenance),
reachable: c.reachable,
reachability_reason: c.reachabilityReason,
})),
`(repo_id, channel, value) DO UPDATE SET
role = EXCLUDED.role,
name = EXCLUDED.name,
score = EXCLUDED.score,
confidence = EXCLUDED.confidence,
provenance = EXCLUDED.provenance,
reachable = EXCLUDED.reachable,
reachability_reason = EXCLUDED.reachability_reason,
last_refreshed = NOW(),
updated_at = NOW(),
deleted_at = NULL`,
Expand Down
Loading
Loading