|
24 | 24 | //! | POST | `/_ts/admin/keys/deactivate` | [`handle_deactivate_key`] | |
25 | 25 | //! | GET | `/_ts/admin/ec` | [`handle_admin_ec_lookup`] | |
26 | 26 | //! | GET | `/_ts/admin/ec/{id}` | [`handle_admin_ec_lookup`] | |
| 27 | +//! | GET | `/_ts/admin/eids` | [`handle_admin_eids_lookup`] | |
27 | 28 | //! | POST | `/_ts/api/v1/batch-sync` | [`handle_batch_sync`] | |
28 | 29 | //! | GET | `/_ts/api/v1/identify` | [`handle_identify`] | |
29 | 30 | //! | GET | `/_ts/set-tester` | [`handle_set_tester`] | |
@@ -100,7 +101,7 @@ use trusted_server_core::auction::endpoints::handle_auction; |
100 | 101 | use trusted_server_core::auction::{AuctionOrchestrator, build_orchestrator}; |
101 | 102 | use trusted_server_core::constants::{COOKIE_SHAREDID, COOKIE_TS_EIDS}; |
102 | 103 | use trusted_server_core::ec::EcContext; |
103 | | -use trusted_server_core::ec::admin::handle_admin_ec_lookup; |
| 104 | +use trusted_server_core::ec::admin::{handle_admin_ec_lookup, handle_admin_eids_lookup}; |
104 | 105 | use trusted_server_core::ec::batch_sync::handle_batch_sync; |
105 | 106 | use trusted_server_core::ec::consent::ec_consent_withdrawn; |
106 | 107 | use trusted_server_core::ec::device::DeviceSignals; |
@@ -576,6 +577,10 @@ async fn run_named_route( |
576 | 577 | let partner_registry = PartnerRegistry::from_config(&state.settings.ec.partners)?; |
577 | 578 | handle_admin_ec_lookup(kv.as_ref(), &partner_registry, &req) |
578 | 579 | } |
| 580 | + NamedRouteHandler::AdminEidsLookup => { |
| 581 | + let partner_registry = PartnerRegistry::from_config(&state.settings.ec.partners)?; |
| 582 | + handle_admin_eids_lookup(&partner_registry, &req) |
| 583 | + } |
579 | 584 | NamedRouteHandler::LegacyAdminDenied => Ok(legacy_admin_alias_denied()), |
580 | 585 | NamedRouteHandler::BatchSync => { |
581 | 586 | // Dispatched by execute_named before EC state is built. |
@@ -999,6 +1004,7 @@ enum NamedRouteHandler { |
999 | 1004 | RotateKey, |
1000 | 1005 | DeactivateKey, |
1001 | 1006 | AdminEcLookup, |
| 1007 | + AdminEidsLookup, |
1002 | 1008 | /// Legacy `/admin/keys/*` aliases — denied locally with 404 so they never |
1003 | 1009 | /// reach the publisher fallback (which would leak admin credentials). |
1004 | 1010 | LegacyAdminDenied, |
@@ -1063,6 +1069,13 @@ const NAMED_ROUTES: &[NamedRoute] = &[ |
1063 | 1069 | primary_methods: &[Method::GET], |
1064 | 1070 | handler: NamedRouteHandler::AdminEcLookup, |
1065 | 1071 | }, |
| 1072 | + // Admin EIDs echo: decodes the request's ts-eids/sharedId cookies with |
| 1073 | + // an ingestion preview. Pure request inspection — no KV access. |
| 1074 | + NamedRoute { |
| 1075 | + path: "/_ts/admin/eids", |
| 1076 | + primary_methods: &[Method::GET], |
| 1077 | + handler: NamedRouteHandler::AdminEidsLookup, |
| 1078 | + }, |
1066 | 1079 | // The legacy non-`/_ts` aliases (`/admin/keys/*`) are denied locally with a |
1067 | 1080 | // 404 instead of executing key operations: the production basic-auth handler |
1068 | 1081 | // regex `^/_ts/admin` does not match them, and letting them fall through to |
@@ -1670,6 +1683,20 @@ mod tests { |
1670 | 1683 | "{path} must have GET as its only primary method" |
1671 | 1684 | ); |
1672 | 1685 | } |
| 1686 | + |
| 1687 | + let eids_route = NAMED_ROUTES |
| 1688 | + .iter() |
| 1689 | + .find(|route| route.path == "/_ts/admin/eids") |
| 1690 | + .expect("should register /_ts/admin/eids as a named route"); |
| 1691 | + assert!( |
| 1692 | + matches!(eids_route.handler, NamedRouteHandler::AdminEidsLookup), |
| 1693 | + "/_ts/admin/eids must map to the admin EIDs lookup handler" |
| 1694 | + ); |
| 1695 | + assert_eq!( |
| 1696 | + eids_route.primary_methods, |
| 1697 | + &[Method::GET], |
| 1698 | + "/_ts/admin/eids must have GET as its only primary method" |
| 1699 | + ); |
1673 | 1700 | } |
1674 | 1701 |
|
1675 | 1702 | #[test] |
|
0 commit comments