Initialize VG-Environment from stable VG-IV baseline
Dieser Commit ist enthalten in:
@@ -0,0 +1,150 @@
|
||||
const REQUEST_DEDUPE_WINDOW_MS = 60 * 1000;
|
||||
const REQUEST_CORRELATION_WINDOW_MS = 5 * 60 * 1000;
|
||||
const OBSERVED_REQUEST_RECORDING_SOURCE = "vendorget_background_mirror";
|
||||
const observedRequestFingerprints = new Map();
|
||||
|
||||
async function handleObservedRequest(details) {
|
||||
if (!(await isRequestMonitoringEnabled())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasConsentQueryParam(details.url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEvidenceWriteSuspended()) {
|
||||
console.info("VendorGet-IV evidence write skipped: maintenance mode");
|
||||
return;
|
||||
}
|
||||
|
||||
// The browser request is the primary observation; VG-IV records a mirror copy
|
||||
// with its own recordedAt timestamp for provenance.
|
||||
const requestFingerprint = await buildObservedRequestFingerprint(details);
|
||||
const requestFingerprintSource = buildObservedRequestFingerprintSource(details);
|
||||
const observedAt = new Date(details.timeStamp).toISOString();
|
||||
const recordedAt = new Date().toISOString();
|
||||
const correlation = buildObservedRequestCorrelation(
|
||||
details.tabId,
|
||||
details.frameId,
|
||||
observedAt
|
||||
);
|
||||
const now = Date.now();
|
||||
const existingFingerprint = observedRequestFingerprints.get(requestFingerprint);
|
||||
const observedRequest = {
|
||||
schemaVersion: 1,
|
||||
requestFingerprint: requestFingerprint,
|
||||
requestFingerprintSource: requestFingerprintSource,
|
||||
recordedAt: recordedAt,
|
||||
recordingSource: OBSERVED_REQUEST_RECORDING_SOURCE,
|
||||
firstSeenAt: observedAt,
|
||||
lastSeenAt: observedAt,
|
||||
seenCount: 1,
|
||||
request: {
|
||||
url: details.url,
|
||||
origin: requestFingerprintSource.origin,
|
||||
pathname: requestFingerprintSource.pathname,
|
||||
method: details.method,
|
||||
type: details.type,
|
||||
thirdParty: details.thirdParty
|
||||
},
|
||||
consentParams: {
|
||||
gdpr: requestFingerprintSource.consentParams.gdpr,
|
||||
gdpr_consent: requestFingerprintSource.consentParams.gdpr_consent,
|
||||
addtlConsent: requestFingerprintSource.consentParams.addtlConsent
|
||||
},
|
||||
context: {
|
||||
tabId: details.tabId,
|
||||
frameId: details.frameId
|
||||
},
|
||||
correlation: correlation
|
||||
};
|
||||
|
||||
if (
|
||||
existingFingerprint &&
|
||||
now - existingFingerprint.lastSeenAt < REQUEST_DEDUPE_WINDOW_MS
|
||||
) {
|
||||
existingFingerprint.lastSeenAt = now;
|
||||
existingFingerprint.seenCount += 1;
|
||||
await persistObservedRequest(observedRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
const seenCount = existingFingerprint
|
||||
? existingFingerprint.seenCount + 1
|
||||
: 1;
|
||||
|
||||
observedRequestFingerprints.set(requestFingerprint, {
|
||||
lastSeenAt: now,
|
||||
seenCount: seenCount
|
||||
});
|
||||
|
||||
await persistObservedRequest(observedRequest);
|
||||
|
||||
const normalizedObject = {
|
||||
observedAt: observedAt,
|
||||
recordedAt: recordedAt,
|
||||
requestId: details.requestId,
|
||||
tabId: details.tabId,
|
||||
frameId: details.frameId,
|
||||
url: details.url,
|
||||
method: details.method,
|
||||
type: details.type,
|
||||
thirdParty: details.thirdParty,
|
||||
requestFingerprint: requestFingerprint,
|
||||
seenCount: seenCount,
|
||||
requestFingerprintSource: requestFingerprintSource
|
||||
};
|
||||
|
||||
console.log("VendorGet-IV observed request", normalizedObject);
|
||||
}
|
||||
|
||||
function hasConsentQueryParam(url) {
|
||||
try {
|
||||
const params = new URL(url).searchParams;
|
||||
|
||||
return (
|
||||
params.has("gdpr") ||
|
||||
params.has("gdpr_consent") ||
|
||||
params.has("addtlConsent")
|
||||
);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function buildObservedRequestCorrelation(tabId, frameId, observedAt) {
|
||||
const latestConsentState = getLatestConsentStateForRequest(tabId, frameId);
|
||||
|
||||
if (!latestConsentState) {
|
||||
return buildEmptyObservedRequestCorrelation();
|
||||
}
|
||||
|
||||
const requestTime = Date.parse(observedAt);
|
||||
const consentTime = Date.parse(latestConsentState.capturedAt);
|
||||
|
||||
if (!Number.isFinite(requestTime) || !Number.isFinite(consentTime)) {
|
||||
return buildEmptyObservedRequestCorrelation();
|
||||
}
|
||||
|
||||
const deltaMs = requestTime - consentTime;
|
||||
|
||||
if (deltaMs < 0 || deltaMs > REQUEST_CORRELATION_WINDOW_MS) {
|
||||
return buildEmptyObservedRequestCorrelation();
|
||||
}
|
||||
|
||||
return {
|
||||
stateFingerprint: latestConsentState.stateFingerprint,
|
||||
deltaMs: deltaMs,
|
||||
method: "latest_in_memory_same_tab_frame",
|
||||
windowMs: REQUEST_CORRELATION_WINDOW_MS
|
||||
};
|
||||
}
|
||||
|
||||
function buildEmptyObservedRequestCorrelation() {
|
||||
return {
|
||||
stateFingerprint: null,
|
||||
deltaMs: null,
|
||||
method: null,
|
||||
windowMs: REQUEST_CORRELATION_WINDOW_MS
|
||||
};
|
||||
}
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren