Files
OpenFUT-Bridge/src/routes/health.rs
T
funman300 eae3e72fd9 Phase 13: web dashboard at /_bridge/dashboard
Single-page club management UI served by the bridge. The Core URL is
injected server-side so client JS calls Core directly without routing
through the proxy. Vanilla HTML/CSS/JS, dark theme matching admin.html.

Sections: Club (name/manager/coins/stats edit), Collection (filterable
card grid with stat bars + chemistry/training pills), Packs (open with
modal, history), Objectives (progress bars + one-click claim), Division
(W/D/L record, season progress, rivals weekly claim), FUT Champions
(current session with in-browser match simulation, claim, history),
Notifications (badge count in nav).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 17:18:10 -07:00

163 lines
6.3 KiB
Rust

use axum::{
extract::State,
http::{header, StatusCode},
response::{Html, IntoResponse, Response},
Json,
};
use serde_json::{json, Value};
use crate::proxy::ProxyState;
pub async fn get_health() -> (StatusCode, Json<Value>) {
(
StatusCode::OK,
Json(json!({
"status": "ok",
"service": "openfut-bridge",
"version": env!("CARGO_PKG_VERSION"),
"note": "This proxy captures FIFA 23 traffic and routes known endpoints to OpenFUT Core."
})),
)
}
/// Serve the TLS certificate as a downloadable PEM file.
///
/// Users navigate to `https://<bridge-ip>:8443/_bridge/cert.pem` in a browser,
/// download the file, and install it as a trusted CA in their OS or game console.
pub async fn get_cert(State(state): State<ProxyState>) -> Response {
match &state.cert_pem {
Some(pem) => (
StatusCode::OK,
[
(header::CONTENT_TYPE, "application/x-pem-file"),
(
header::CONTENT_DISPOSITION,
"attachment; filename=\"openfut-ca.pem\"",
),
],
pem.as_ref().clone(),
)
.into_response(),
None => (
StatusCode::NOT_FOUND,
Json(json!({ "error": "TLS is not enabled; no certificate to download" })),
)
.into_response(),
}
}
/// Club management dashboard served at `/_bridge/dashboard`.
///
/// Injects the Core URL so client-side JS can call Core directly without going through the proxy.
pub async fn get_dashboard(State(state): State<ProxyState>) -> Response {
let template = include_str!("../dashboard.html");
let html = template.replace("{{CORE_URL}}", &state.config.core_url);
Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, "text/html; charset=utf-8")
.body(axum::body::Body::from(html))
.unwrap()
}
/// HTML setup guide for connecting FIFA 23 to OpenFUT Bridge.
pub async fn get_guide(State(state): State<ProxyState>) -> Html<String> {
let host = state
.config
.listen_addr
.split(':')
.next()
.unwrap_or("localhost");
let tls = state.config.tls_enabled;
let scheme = if tls { "https" } else { "http" };
let port = state.config.listen_addr.split(':').next_back().unwrap_or("8080");
let bridge_url = format!("{scheme}://{host}:{port}");
let core_url = &state.config.core_url;
let guide = format!(
r#"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OpenFUT Bridge — Setup Guide</title>
<style>
body {{ font-family: system-ui, sans-serif; max-width: 780px; margin: 0 auto; padding: 2rem; background: #0a0a0a; color: #e0e0e0; }}
h1 {{ color: #f5a623; }} h2 {{ color: #a0c4ff; border-bottom: 1px solid #333; padding-bottom: 4px; }}
code {{ background: #1c1c1c; padding: 2px 6px; border-radius: 3px; font-family: monospace; }}
pre {{ background: #1c1c1c; padding: 1rem; border-radius: 6px; overflow-x: auto; }}
.ok {{ color: #5fbb5f; }} .warn {{ color: #f5a623; }}
a {{ color: #a0c4ff; }}
.step {{ margin: 1.2rem 0; padding: 1rem; background: #141414; border-left: 3px solid #f5a623; border-radius: 0 6px 6px 0; }}
</style>
</head>
<body>
<h1>OpenFUT Bridge — Setup Guide</h1>
<p><span class="ok">&#x2713;</span> Bridge is running at <code>{bridge_url}</code></p>
<p>Core API: <code>{core_url}</code></p>
<h2>How it works</h2>
<p>OpenFUT Bridge sits between FIFA 23 and EA's servers. It intercepts FUT API calls and
routes supported endpoints to OpenFUT Core (your local offline backend). Unsupported
endpoints return placeholder responses so the game stays stable.</p>
<h2>Step 1 — Redirect FIFA 23 traffic</h2>
<div class="step">
<p>Add these entries to your <strong>hosts file</strong> (requires admin/root):</p>
<pre>
# Point FIFA 23 FUT traffic to OpenFUT Bridge
127.0.0.1 fut.ea.com
127.0.0.1 utas.mob.v4.fut.ea.com
</pre>
<ul>
<li>Windows: <code>C:\Windows\System32\drivers\etc\hosts</code></li>
<li>macOS / Linux: <code>/etc/hosts</code></li>
</ul>
</div>
<h2>Step 2 — Install the TLS certificate (HTTPS only)</h2>
{cert_section}
<h2>Step 3 — Launch FIFA 23</h2>
<div class="step">
<p>Start FIFA 23 and navigate to <strong>Ultimate Team</strong>. The bridge will capture
and proxy FUT API calls. Open <code>{bridge_url}/_bridge/admin</code> in your browser to
watch traffic in real time.</p>
</div>
<h2>Supported endpoints</h2>
<p>See <code><a href="/_bridge/status">/_bridge/status</a></code> for a full list of mapped
and unknown endpoints seen so far.</p>
<h2>Troubleshooting</h2>
<ul>
<li><strong>Game shows "FUT servers unavailable":</strong> make sure the hosts file is saved and DNS is flushed (<code>ipconfig /flushdns</code> on Windows).</li>
<li><strong>Certificate error in browser:</strong> the self-signed cert must be trusted by the OS or the game's certificate store.</li>
<li><strong>Bridge not reaching Core:</strong> check that <code>openfut-core</code> is running and <code>CORE_URL</code> is set correctly (default <code>http://127.0.0.1:3000</code>).</li>
</ul>
<p style="color:#555; font-size:0.85em; margin-top:3rem;">
OpenFUT is an <strong>offline</strong> replacement backend for legitimate FIFA 23 owners.
It does not connect to EA servers or enable online multiplayer.
</p>
</body>
</html>"#,
cert_section = if tls {
format!(
r#"<div class="step">
<p>Download and install the bridge's self-signed CA certificate so FIFA 23 trusts HTTPS connections:</p>
<ol>
<li>Open <a href="/_bridge/cert.pem"><code>{bridge_url}/_bridge/cert.pem</code></a> and save it.</li>
<li><strong>Windows:</strong> double-click the file → "Install Certificate" → "Local Machine" → "Trusted Root Certification Authorities".</li>
<li><strong>macOS:</strong> double-click the file → Keychain Access → trust "Always".</li>
<li><strong>Linux:</strong> copy to <code>/usr/local/share/ca-certificates/</code> and run <code>update-ca-certificates</code>.</li>
</ol>
</div>"#
)
} else {
"<div class=\"step\"><p class=\"warn\">TLS is disabled — set <code>TLS_ENABLED=true</code> to enable HTTPS (required for FIFA 23 interception).</p></div>".to_string()
}
);
Html(guide)
}