| 1485 | sourceOccurredAt: finding.raw_data.updated_at, |
| 1486 | eventKey: deriveSecurityFindingAuditEventKey([ |
| 1487 | ...keyBase, |
| 1488 | SecurityAuditLogAction.FindingSeverityChanged, |
| 1489 | finding.raw_data.updated_at, |
| 1490 | upserted.previousSeverity, |
| 1491 | upserted.effectiveSeverity, |
| 1492 | ]), |
| 1493 | sourceContext: SecurityFindingAuditSourceContext.SecuritySync, |
| 1494 | beforeState: { severity: upserted.previousSeverity }, |
| 1495 | afterState: { severity: upserted.effectiveSeverity }, |
| 1496 | metadata: commonMetadata, |
| 1497 | }); |
| 1498 | } |
| 1499 | |
| 1500 | if (upserted.previousStatus !== null && upserted.previousStatus !== upserted.effectiveStatus) { |
| 1501 | const action = getSyncStatusAuditAction(finding.raw_data.state); |
| 1502 | const sourceOccurredAt = getStatusSourceOccurredAt(finding); |
| 1503 | await insertSecurityFindingAuditEvent(db, { |
| 1504 | owner: auditOwner, |
| 1505 | finding: auditFinding, |
| 1506 | actor: SECURITY_FINDING_AUDIT_SYSTEM_ACTOR, |
| 1507 | action, |
| 1508 | occurredAt, |
| 1509 | sourceOccurredAt, |
| 1510 | eventKey: deriveSecurityFindingAuditEventKey([ |
| 1511 | ...keyBase, |
| 1512 | action, |
| 1513 | sourceOccurredAt, |
| 1514 | upserted.previousStatus, |
| 1515 | upserted.effectiveStatus, |
| 1516 | ]), |
| 1517 | sourceContext: SecurityFindingAuditSourceContext.SecuritySync, |
| 1518 | beforeState: { status: upserted.previousStatus }, |
| 1519 | afterState: { |
| 1520 | status: upserted.effectiveStatus, |
| 1521 | ...(finding.ignored_reason ? { reason_code: finding.ignored_reason } : {}), |
| 1522 | ...(finding.fixed_at ? { fixed_at: new Date(finding.fixed_at).toISOString() } : {}), |
| 1523 | }, |
| 1524 | metadata: commonMetadata, |
| 1525 | }); |
| 1526 | } |
| 1527 | } |
| 1528 | |
| 1529 | function getSyncStatusAuditAction(state: DependabotAlertState): SecurityAuditLogAction { |
| 1530 | if (state === 'auto_dismissed') return SecurityAuditLogAction.FindingAutoDismissed; |
| 1531 | if (state === 'dismissed') return SecurityAuditLogAction.FindingDismissed; |
| 1532 | return SecurityAuditLogAction.FindingStatusChange; |
| 1533 | } |
| 1534 | |
| 1535 | function getStatusSourceOccurredAt(finding: ParsedSecurityFinding): string { |
| 1536 | if (finding.raw_data.state === 'auto_dismissed') { |
| 1537 | return ( |
| 1538 | finding.raw_data.auto_dismissed_at ?? |
| 1539 | finding.raw_data.dismissed_at ?? |
| 1540 | finding.raw_data.updated_at |
| 1541 | ); |
| 1542 | } |
| 1543 | if (finding.raw_data.state === 'dismissed') { |
| 1544 | return finding.raw_data.dismissed_at ?? finding.raw_data.updated_at; |