Add EC consent logging and Sourcepoint consent support#679
Open
ChristianPavilonis wants to merge 90 commits intoedge-cookie-sourcepoint-consentfrom
Open
Add EC consent logging and Sourcepoint consent support#679ChristianPavilonis wants to merge 90 commits intoedge-cookie-sourcepoint-consentfrom
ChristianPavilonis wants to merge 90 commits intoedge-cookie-sourcepoint-consentfrom
Conversation
- Rename 'Synthetic ID' to 'Edge Cookie (EC)' across all external-facing identifiers, config, internal Rust code, and documentation - Simplify EC hash generation to use only client IP (IPv4 or /64-masked IPv6) with HMAC-SHA256, removing User-Agent, Accept-Language, Accept-Encoding, random_uuid inputs and Handlebars template rendering - Downgrade EC ID generation logs to trace level since client IP and EC IDs are sensitive data - Remove unused counter_store and opid_store config fields and KV store declarations (vestigial from template-based generation) - Remove handlebars dependency Breaking changes: wire field synthetic_fresh → ec_fresh, response headers X-Synthetic-ID → X-TS-EC, cookie synthetic_id → ts-ec, query param synthetic_id → ts-ec, config section [synthetic] → [edge_cookie]. Closes #462
…igration - Add ec/ module with EcContext lifecycle, generation, cookies, and consent - Compute cookie domain from publisher.domain, move EC cookie helpers - Fix auction consent gating, restore cookie_domain for non-EC cookies - Add integration proxy revocation, refactor EC parsing, clean up ec_hash - Remove fresh_id and ec_fresh per EC spec §12.1 - Migrate [edge_cookie] config to [ec] per spec §14
Implement Story 3 (#536): KV-backed identity graph with compare-and-swap concurrency, partner ID upserts, tombstone writes for consent withdrawal, and revive semantics. Includes schema types, metadata, 300s last-seen debounce, and comprehensive unit tests. Also incorporates earlier foundation work: EC module restructure, config migration from [edge_cookie] to [ec], cookie domain computation, consent gating fixes, and integration proxy revocation support.
Implement Story 4 (#537): partner KV store with API key hashing, POST /admin/partners/register with basic-auth protection, strict field validation (ID format, URL allowlists, domain normalization), and pull-sync config validation. Includes index-based API key lookup and comprehensive unit tests.
Implement Story 5 (#538): centralize EC cookie set/delete and KV tombstone writes in finalize_response(), replacing inline mutation scattered across publisher and proxy handlers. Adds consent-withdrawal cleanup, EC header propagation on proxy requests, and docs formatting.
Implement Story 8 (#541): POST /api/v1/sync with Bearer API key auth, per-partner rate limiting, batch size cap, per-mapping validation and rejection reasons, 200/207 response semantics, tolerant Bearer parsing, and KV-abort on store unavailability.
Implement Story 9 (#542): server-to-server pull sync that runs after send_to_client() on organic traffic only. Refactors the Fastly adapter entrypoint from #[fastly::main] to explicit Request::from_client() + send_to_client() to enable post-send background work. Pull sync enumerates pull-enabled partners, checks staleness against pull_sync_ttl_sec, validates URL hosts against the partner allowlist, enforces hourly rate limits, and dispatches concurrent outbound GETs with Bearer auth. Responses with uid:null or 404 are no-ops; valid UIDs are upserted into the identity graph. Includes EC ID format validation to prevent dispatch on spoofed values, partner list_registered() for KV store enumeration, and configurable pull_sync_concurrency (default 3).
Implement Story 11 (#544): Viceroy-driven E2E tests covering full EC lifecycle (generation, pixel sync, identify, batch sync, consent withdrawal, auth rejection). Adds EC test helpers with manual cookie tracking, minimal origin server with graceful shutdown, and required KV store fixtures. Fixes integration build env vars.
Consolidate is_valid_ec_hash and current_timestamp into single canonical definitions to eliminate copy-paste drift across the ec/ module tree. Fix serialization error variants in admin and batch_sync to use Ec instead of Configuration. Add scaling and design-decision documentation for partner store enumeration, rate limiter burstiness, and plaintext pull token storage. Use test constructors consistently in identify and finalize tests.
- Rename ssc_hash → ec_hash in batch sync wire format (§9.3) - Strip x-ts-* prefix headers in copy_custom_headers (§15) - Strip dynamic x-ts-<partner_id> headers in clear_ec_on_response (§5.2) - Add PartnerNotFound and PartnerAuthFailed error variants (§16) - Rename Ec error variant → EdgeCookie (§16) - Validate EC IDs at read time, discard malformed values (§4.2) - Add rotating hourly offset for pull sync partner dispatch (§10.3) - Add _pull_enabled secondary index for O(1+N) pull sync reads (§13.1)
…nd cleanup - Add body size limit (64 KiB) to partner registration - Validate partner UID length (max 512 bytes) in batch sync and sync pixel - Replace linear scan with binary search in encode_eids_header - Use constant-time comparison inline in partner lookup, remove unused verify_api_key - Remove unused PartnerAuthFailed error variant, fix PartnerNotFound → 404 - Add Access-Control-Max-Age CORS header to identify endpoint - Tighten consent-denied integration test to expect only 403 - Add stability doc-comment to normalize_ip - Log warning instead of silent fallback on SystemTime failure
…ror variants Resolve integration issues from rebasing onto feature/ssc-update: - Restore prepare_runtime() and validate_cookie_domain() lost in conflict resolution - Add InsecureDefault error variant and wire reject_placeholder_secrets() into get_settings() - Add sha2/subtle imports for constant-time auth comparison - Fix error match arms (Ec → EdgeCookie, remove nonexistent PartnerAuthFailed) - Fix orchestrator error handling to use send_to_client() pattern - Remove dead cookie helpers superseded by ec/cookies module
Subresource requests (fonts, images, CSS) may omit the Sec-GPC header, causing the server to incorrectly generate ts-ec cookies when the user has opted out via Global Privacy Control. Gate generate_if_needed() on the request Accept header containing text/html so only navigations trigger EC identity creation.
Move admin route matching and basic-auth coverage to /_ts/admin for a hard cutover, and align tests and docs so operational guidance matches runtime behavior.
Addresses issue #612 - spec now correctly documents that the full EC ID ({64-hex}.{6-alnum}) is used as the KV store key, not just the 64-char hash prefix. Changes: - Updated §4.1: ec_hash() now documented as for logging/debugging only - Updated §7.2: KV key description changed from '64-character hex hash' to 'Full EC ID in {64-char hex}.{6-char alphanumeric} format' - Updated §7.3: All KvIdentityGraph method parameters renamed from ec_hash to ec_id with proper documentation - Updated §9.3: Batch sync request field renamed from ec_hash to ec_id - Updated §9.4: Validation and error reasons updated (invalid_ec_hash → invalid_ec_id, ec_hash_not_found → ec_id_not_found) - Updated §10.4: Pull sync URL parameter changed from ec_hash to ec_id - Updated consent pipeline integration throughout to use full EC ID - Updated all rate limiting descriptions (per EC ID, not per hash) Rationale: The random suffix provides uniqueness for users behind the same NAT/proxy infrastructure who would otherwise share identical IP-derived hash prefixes.
Extends EC KV schema for cross-property identity resolution: - Add asn field to GeoInfo (from Fastly geo.as_number()) - Add asn and dma fields to KvGeo for network identification - Add KvDomainVisit and KvPubProperties for consortium-level domain tracking - Add pub_properties field to KvEntry with 50-domain cap - Track publisher domain visits in KvEntry::new() and update_last_seen() - Respect existing 300s debounce for organic requests only All new fields use Option types or serde(default) for backward compatibility. Existing v1 entries continue to deserialize without error.
Implements cluster size evaluation to distinguish individual users from shared networks (VPNs, corporate offices): - Add KvNetwork struct with cluster_size and last_evaluated timestamp - Add network field to KvEntry with TTL-gated cluster rechecks - Add cluster_size to KvMetadata and IdentifyResponse - Implement count_hash_prefix_keys() to list keys with common prefix - Implement evaluate_cluster() on KvIdentityGraph (one-page, 100-key limit) - Call cluster evaluation in handle_identify endpoint - Return cluster_size in JSON body and x-ts-cluster-size header - Add cluster_trust_threshold (default 10) and cluster_recheck_secs (default 3600) config Cluster evaluation uses best-effort semantics: size unknown if list exceeds 100 keys. Cache hit avoids re-evaluation within recheck interval.
Derives coarse browser signals from TLS/H2/UA on every request to gate EC identity operations. Unrecognized clients (known_browser != true) are proxied normally but leave no trace in the identity graph. - Add KvDevice struct (is_mobile, ja4_class, platform_class, h2_fp_hash, known_browser) and device field on KvEntry, written once on creation - Add ec/device.rs with DeviceSignals::derive(), UA parsing, JA4 Section 1 extraction, H2 fingerprint hashing, known browser allowlist (Chrome/ Safari/Firefox) - Add is_mobile and known_browser to KvMetadata for fast propagation checks - Wire DeviceSignals through EcContext to KvEntry creation path - Add bot gate in Fastly adapter: suppress KV graph, ec_finalize_response, and pull sync when known_browser != Some(true)
…bot gate Document all KV schema additions implemented in the preceding commits: geo extensions (asn/dma), publisher domain tracking, network cluster evaluation, device signal derivation, and the bot gate architecture. - Add §7A Device Signals and Bot Gate (signal derivation, allowlist, bot gate behavior matrix, KvDevice write policy, privacy rationale) - Update §7.2 with full KvEntry schema including KvGeo, KvPubProperties, KvDomainVisit, KvDevice, KvNetwork, and extended KvMetadata - Update §2 architecture diagram with Phase 0 bot gate step - Update §4.3 EcContext with device_signals field - Update §5.4 lifecycle with Phase 0 and ec_finalize gating - Update §11 /identify with cluster_size in JSON and x-ts-cluster-size header - Update §14 config with cluster_trust_threshold and cluster_recheck_secs - Update §17.1 main.rs pseudocode with full bot gate wiring
The known_browser fingerprint allowlist (3 entries) was too narrow and blocked legitimate browsers whose JA4/H2 combinations were not listed. Replace the gate with DeviceSignals::looks_like_browser() which checks for signal presence: ja4_class.is_some() && platform_class.is_some(). Real browsers always produce both; raw HTTP clients typically lack one or both. known_browser is still computed and stored on KvDevice for analytics but no longer gates identity operations.
Entries created before pub_properties was added have the field as None. The previous code only updated pub_properties when it already existed (if let Some), so returning users on pre-existing entries never got domain tracking. Now when pub_properties is None, update_last_seen initializes it with the current domain as origin_domain and first seen_domains entry. This is a one-time backfill per entry — subsequent visits take the existing update path.
Prebid's liveIntentIdSystem.js uses a dynamic require() inside a build-flag-guarded branch that their gulp pipeline dead-codes via constant folding. esbuild leaves the require() in the output, causing ReferenceError: require is not defined at browser runtime. Remove from the bundle until we add an esbuild resolver plugin (or switch to Prebid's own build pipeline) — tracked as a follow-up in the design spec.
Introduces TSJS_PREBID_USER_IDS env var (mirroring TSJS_PREBID_ADAPTERS) to control which Prebid User ID submodules are bundled. The hardcoded imports in index.ts are replaced with a generated file written by build-all.mjs at build time, defaulting to the same 13-submodule set. - build-all.mjs: generatePrebidUserIds() validates names, denylists liveIntentIdSystem, and writes _user_ids.generated.ts. Existence check also probes dist/src/public/ to handle modules shipped as .ts in sources (sharedIdSystem). - index.ts: replaces 13 hardcoded submodule imports with import './_user_ids.generated' - _user_ids.generated.ts: committed default with all 13 submodules - Tests: updated mocks and regression guard; added 9 syncPrebidEidsCookie behavior tests - Docs: new "User ID Modules" section in prebid.md with TSJS_PREBID_USER_IDS usage; spec follow-up #1 marked complete
__gpp and __gpp_sid are read by the Rust server over HTTPS; they must be Secure. Also sets Max-Age=86400 (matching ts-eids) so stale consent state doesn't outlast the session, and replaces the legacy expires= deletion pattern with Max-Age=0.
… and Move logging initialization into Fastly adapter (#610) * Rename crates to trusted-server-core and trusted-server-adapter-fastly Rename crates/common → crates/trusted-server-core and crates/fastly → crates/trusted-server-adapter-fastly following the EdgeZero naming convention. Add EdgeZero workspace dependencies pinned to rev 170b74b. Update all references across docs, CI workflows, scripts, agent files, and configuration. * Add platform abstraction layer with traits and RuntimeServices Introduces trusted-server-core::platform with PlatformConfigStore, PlatformSecretStore, PlatformKvStore, PlatformBackend, PlatformHttpClient, and PlatformGeo traits alongside ClientInfo, PlatformError, and RuntimeServices. Wires the Fastly adapter implementations and threads RuntimeServices into route_request. Moves GeoInfo to platform/types as platform-neutral data and adds geo_from_fastly for field mapping. * Address platform layer review feedback - Defer KV store opening: replace early error return with a local UnavailableKvStore fallback so routes that do not need synthetic ID access succeed when the KV store is missing or temporarily unavailable - Use ConfigStore::try_open + try_get and SecretStore::try_get throughout FastlyPlatformConfigStore and FastlyPlatformSecretStore to honour the Result contract instead of panicking on open/lookup failure - Encapsulate RuntimeServices service fields as pub(crate) with public getter methods (config_store, secret_store, backend, http_client, geo) and a pub new() constructor; adapter updated to use new() - Reference #487 in FastlyPlatformHttpClient stub (PR 6 implements it) - Remove unused KvPage re-export from platform/mod.rs - Use super::KvHandle shorthand in RuntimeServices::kv_handle() * Reject host strings containing control characters in BackendConfig * Fix clippy error * Validate scheme and host for control characters in BackendConfig * Address review findings on platform abstraction layer * Address review findings on platform abstraction layer * Add config store read path and storage module split - Split fastly_storage.rs into storage/{config_store,secret_store,api_client,mod}.rs - Add PlatformConfigStore read path via FastlyPlatformConfigStore::get using ConfigStore::try_open/try_get - Add PlatformError::NotImplemented variant; stub write methods on FastlyPlatformConfigStore and FastlyPlatformSecretStore - Add StoreName/StoreId newtypes with From<String>, From<&str>, AsRef<str> - Add UnavailableKvStore to core platform module - Add RuntimeServicesBuilder replacing 7-arg constructor - Migrate get_active_jwks and handle_trusted_server_discovery to use &RuntimeServices - Update call sites in signing.rs, rotation.rs, main.rs - Add success-path test for handle_trusted_server_discovery using StubJwksConfigStore - Fix test_parse_cookies_to_jar_empty typo (was emtpy) * Harden legacy config-store reads and align Fastly adapter stubs * Address storage review feedback * Resolved github-advanced-security bot problems * Address PR review feedback on platform abstraction layer - Make StoreName and StoreId inner fields private; From/AsRef provide all needed construction and access - Add #[deprecated] to GeoInfo::from_request with #[allow(deprecated)] at the three legacy call sites to track migration progress - Enumerate the six platform traits in the platform module doc comment - Extract backend_config_from_spec helper to remove duplicate BackendConfig construction in predict_name and ensure - Replace .into_iter().collect() with .to_vec() on secret plaintext bytes - Remove unused bytes dependency from trusted-server-adapter-fastly - Add comment on SecretStore::open clarifying it already returns Result (unlike ConfigStore::open which panics) * Add PR 4 design spec for secret store trait (read-only) * Clarify test scope and deferred branches in PR 4 spec * Add implementation plan for PR 4 secret store trait * Add test for get_secret_bytes open-failure path * Add NotImplemented tests for FastlyPlatformSecretStore write stubs * Inline StoreId binding and add section comment in write-stub tests * Remove plan * Add PR 6 design spec for backend and HTTP client traits * Address spec review findings on PR 6 design * Implement PlatformHttpClient and thread RuntimeServices through proxy layer - Add PlatformHttpClient trait with send(), send_async(), and select() methods - Add PlatformBackend trait with predict_name() and ensure() methods - Add PlatformResponse wrapper around EdgeZero HTTP responses - Add PlatformPendingRequest and PlatformSelectResult for auction fan-out - Thread RuntimeServices through IntegrationProxy::handle(), IntegrationRegistry::handle_proxy(), and all first-party proxy endpoints so handlers can reach the HTTP client - Add StubHttpClient and StubBackend test stubs with build_services_with_http_client helper - Add proxy_request_calls_platform_http_client_send integration test - Fix proxy_with_redirects to stay within 7-arg clippy limit via ProxyRequestHeaders struct - Document Body::Stream limitation in edge_request_to_fastly with warning log - Document intentional duplication of platform_response_to_fastly across proxy and orchestrator - Remove spec file (promoted to plan + implementation) * Address pr review findings * Resolve pr review findings * Add PR7 design spec for geo lookup + client info extract-once Documents the call site migration plan: five Fastly SDK extraction points in trusted-server-core replaced by RuntimeServices::client_info reads, following Phase 1 injection pattern from the EdgeZero migration design. * Fix spec review issues in PR7 design doc - Correct erroneous claim about generate_synthetic_id being called twice via DeviceInfo; it is called once (line 91 for fresh_id), DeviceInfo.ip is a separate req.get_client_ip_addr() call fixed independently - Add before/after snippet for handle_publisher_request call site in main.rs - Add noop_services import instruction for http_util.rs test module - Clarify _services rename (drop underscore, not add new param) in didomi.rs - Clarify nextjs #[allow(deprecated)] annotations are out of scope (different function) * Update PR7 spec to address all five agent review findings - Change RequestInfo::from_request signature to &ClientInfo (not &RuntimeServices) so prebid can call it with context.client_info - Scope SDK-call acceptance criteria to active non-deprecated code only - List all six AuctionContext construction sites including two production sites in orchestrator.rs and three test helpers in orchestrator/prebid - Add explicit warn-and-continue pattern for publisher.rs geo lookup - Correct testing table: formats.rs and endpoints.rs have no test modules; add orchestrator.rs and prebid.rs test helper update rows * Add PR7 implementation plan and address plan review findings Plan covers 6 tasks in compilation-safe order: AuctionContext struct change first, then from_request signature, then synthetic.rs cascade, then publisher geo, then didomi. Includes two new copy_headers unit tests (Some/None). Spec fixes: clarify injection pattern exceptions for &ClientInfo and Option<IpAddr>; reword acceptance criterion to reflect that provider-layer reads flow through AuctionContext.client_info. * Fix three plan review findings and two open questions - Finding 1 (High): Add missing publisher.rs test call site at line ~695 for get_or_generate_synthetic_id — was omitted from Task 3 Step 6 - Finding 2 (Medium): Remove crate::geo::GeoInfo import from endpoints.rs rather than replacing it — type is not used by name after the change, keeping any import fails clippy -D warnings - Finding 3 (Low): Replace interactive git add -p in Task 6 with explicit file staging instruction - Open Q1: Add Task 2 step to update stale handle_publisher_request signature in auction/README.md - Open Q2: Add Task 2 step to update from_request doc comment to reflect ClientInfo-based TLS detection instead of Fastly SDK calls * Broaden two low-severity doc cleanup steps in PR7 plan - Step 7: cover all four stale Fastly-SDK-specific locations in http_util.rs (SPOOFABLE_FORWARDED_HEADERS doc, RequestInfo struct doc, from_request doc, detect_request_scheme doc) - Step 8: replace the whole routing snippet in auction/README.md, not just the one handle_publisher_request line — handle_auction and integration_registry.handle_proxy are also stale in that snippet * Fix two remaining low findings in PR7 plan - Add missing Location 2 (RequestInfo.scheme field doc, line ~67) to Step 7; renumber subsequent locations 3-5 - Replace &runtime_services with runtime_services in Step 5 and README snippet — runtime_services is already &RuntimeServices in route_request * Fix count drift in Step 7: four → five locations * Add client_info field to AuctionContext and fix all construction sites * Change RequestInfo::from_request to take &ClientInfo, thread services into handle_publisher_request * Add Task 2 follow-up coverage and README route fixes * Add services param to generate_synthetic_id, remove Fastly IP/geo calls in formats and endpoints * Revert premature publisher geo change from Task 3 * Replace deprecated GeoInfo::from_request in publisher.rs with services.geo().lookup() * Remove Fastly IP extraction from Didomi copy_headers, use ClientInfo instead * Move IpAddr import to test module level in didomi.rs * Apply rustfmt formatting to didomi.rs, publisher.rs, and synthetic.rs Fix multi-line function call style in didomi.rs, line-break wrapping in publisher.rs test, and import ordering in synthetic.rs test module. * Add test coverage for generate_synthetic_id with concrete client IP Adds noop_services_with_client_ip helper to test_support and a new test that verifies the client_ip path through generate_synthetic_id by asserting the HMAC differs when the IP changes. * Align geo lookup warn log format with codebase convention ({e} not {e:?}) * Apply Prettier formatting to PR7 plan and spec docs * Document content rewriting as platform-agnostic in platform module * Document html_processor as platform-agnostic * Document streaming_processor as platform-agnostic * Fix unresolved doc link: replace EdgeRequest with edgezero_core::http::Request * Add plan for content rewriting * Add plan for PR9: wire signing to store primitives * Add build_services_with_config_and_secret to test_support * Add FastlyManagementApiClient to adapter * Implement FastlyPlatformConfigStore and FastlyPlatformSecretStore write methods via management API Replace FastlyApiClient with FastlyManagementApiClient in the put/delete methods of FastlyPlatformConfigStore and the create/delete methods of FastlyPlatformSecretStore. Remove the now-unused FastlyApiClient import. * Add services to AuctionContext; remove deprecated from_config shim Thread RuntimeServices into AuctionContext so auction providers can access platform stores directly. Update PrebidAuctionProvider to use RequestSigner::from_services(context.services) instead of the now- removed from_config() shim. All construction sites and test helpers updated accordingly. This satisfies the final acceptance criterion of #490: no FastlyConfigStore/FastlySecretStore construction remains in the request_signing/ modules. * Fix rotate/delete atomicity, HTTP verb, idempotent deletes, and weak tests - Revert proxy.rs merge artifact: restore per-request allowed_domains at both redirect_is_permitted call sites; remove dead_code allow and stale comment — integration proxies defaulting to &[] get open mode again as documented - Drop unused trusted-server-js dep from adapter Cargo.toml - Fix check_response: gate body read behind error branch so 2xx paths do not buffer and discard the response body - Remove self-referential SECRET_UPSERT_METHOD test - Reorder write-cost doc so outbound HTTPS round-trip leads; handle-open caching noted as negligible - Refactor make_request to take fastly::http::Method; drop string match and unreachable arm; remove SECRET_UPSERT_METHOD const - Add SigningStoreIds named struct in endpoints.rs; update both call sites to destructure by name * Move logging initialization into Fastly adapter (PR 10) (#610) Move logging initialization into Fastly adapter (PR 10) (#610) - Reverted gratuitous _message rename and record.args() usage in logging.rs, returning to the idiomatic message parameter inside the fern format closure. - Refactored target_label to use .rsplit_once("::") rather than .split("::").last(). This provides a more explicit and robust way to extract the final module segment. - Expanded target_label test coverage to explicitly test edge cases such as inputs without :: separators, empty strings, and inputs with trailing ::.
e7b561a to
d0dd47b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes
crates/trusted-server-core/src/consent/mod.rsallows_ec_creation.crates/trusted-server-core/src/ec/consent.rscrates/trusted-server-core/src/ec/finalize.rscrates/trusted-server-core/src/ec/mod.rscrates/trusted-server-core/src/integrations/registry.rscrates/trusted-server-core/src/publisher.rscrates/trusted-server-adapter-fastly/src/logging.rscrates/js/lib/src/integrations/sourcepoint/index.tscrates/js/lib/test/integrations/sourcepoint/index.test.tscrates/js/lib/build-all.mjscrates/js/lib/src/integrations/prebid/_user_id_modules.generated.tscrates/js/lib/src/integrations/prebid/index.tsuserSyncsettings.crates/js/lib/test/integrations/prebid/index.test.tscrates/trusted-server-core/src/integrations/prebid.rsuser_syncconfig serialization into the injected Prebid JS config.trusted-server.tomlCloses
Closes #
Test plan
cargo test --workspacecargo clippy --workspace --all-targets --all-features -- -D warningscargo fmt --all -- --checkcd crates/js/lib && npx vitest runcd crates/js/lib && npm run formatcd docs && npm run formatcargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1fastly compute servecargo fmt --all;cargo check --workspace;cd crates/js/lib && npx vitest run test/integrations/sourcepoint/index.test.ts test/integrations/prebid/index.test.tsChecklist
unwrap()in production code — useexpect("should ...")tracingmacros (notprintln!)