@@ -120,6 +120,7 @@ use sea_orm::{ConnectOptions, Database};
120120use service:: config:: http:: X_VERSION_HEADER_API ;
121121use service:: db:: constants:: MAX_CONNECTIONS ;
122122use service:: providers:: emuready:: EmuReadyClient ;
123+ use service:: providers:: hasheous:: HasheousClient ;
123124use service:: providers:: igdb:: IgdbClient ;
124125use service:: providers:: launchbox:: LaunchBoxClient ;
125126use service:: providers:: mobygames:: MobyGamesClient ;
@@ -202,6 +203,8 @@ async fn start() -> anyhow::Result<()> {
202203
203204 let er_http_client = Client :: builder ( ) . cookie_store ( false ) . build ( ) ?;
204205
206+ let hasheous_http_client = Client :: builder ( ) . cookie_store ( false ) . build ( ) ?;
207+
205208 let tgdb_http_client = Client :: builder ( ) . cookie_store ( false ) . build ( ) ?;
206209
207210 // DAT downloads use a cookieless client so hostile mirrors cannot set cookies that
@@ -223,6 +226,7 @@ async fn start() -> anyhow::Result<()> {
223226 let ra_client_opt =
224227 build_retroachievements_client ( ra_http_client, redis_conn. clone ( ) , conn. clone ( ) ) ;
225228 let er_client_opt = build_emuready_client ( er_http_client, redis_conn. clone ( ) ) ;
229+ let hasheous_client_opt = build_hasheous_client ( hasheous_http_client, redis_conn. clone ( ) ) ;
226230 let tgdb_client_opt =
227231 build_thegamesdb_client ( tgdb_http_client, redis_conn. clone ( ) , conn. clone ( ) ) ;
228232
@@ -265,6 +269,9 @@ async fn start() -> anyhow::Result<()> {
265269 if let Some ( c) = er_client_opt. clone ( ) {
266270 providers. push ( c as Arc < dyn MetadataProvider > ) ;
267271 }
272+ if let Some ( c) = hasheous_client_opt. clone ( ) {
273+ providers. push ( c as Arc < dyn MetadataProvider > ) ;
274+ }
268275 if let Some ( c) = tgdb_client_opt. clone ( ) {
269276 providers. push ( c as Arc < dyn MetadataProvider > ) ;
270277 }
@@ -579,6 +586,33 @@ fn build_emuready_client(
579586 }
580587}
581588
589+ /// Returns `None` when HASHEOUS_ENABLED is unset or not "true". The Hasheous
590+ /// hash-lookup endpoints are open and unauthenticated; the flag exists so
591+ /// existing deployments do not silently start hitting an external service on
592+ /// next deploy. Matching only. No proxy routes are exposed.
593+ fn build_hasheous_client (
594+ http : Client ,
595+ redis_conn : redis:: aio:: MultiplexedConnection ,
596+ ) -> Option < Arc < HasheousClient > > {
597+ let enabled = env:: var ( "HASHEOUS_ENABLED" )
598+ . unwrap_or_default ( )
599+ . eq_ignore_ascii_case ( "true" ) ;
600+ if !enabled {
601+ warn ! ( "HASHEOUS_ENABLED not set to true, Hasheous provider disabled" ) ;
602+ return None ;
603+ }
604+ match HasheousClient :: new ( http, redis_conn) {
605+ Ok ( c) => {
606+ info ! ( "Hasheous provider enabled" ) ;
607+ Some ( Arc :: new ( c) )
608+ }
609+ Err ( e) => {
610+ warn ! ( "Hasheous provider construction failed, disabled: {e}" ) ;
611+ None
612+ }
613+ }
614+ }
615+
582616/// Returns `None` when TGDB_ENABLED is unset or not "true". TheGamesDB is
583617/// match-only; no proxy routes are exposed. The bootstrap dataset is seeded
584618/// via a migration so no daily import job runs. TGDB_API_KEY is optional;
0 commit comments