Fix five console-level issues surfaced by live-deploy Playwright audit
1. FlightsMap tiles didn't render: MapCanvas inline height:100% resolved
to 0 against min-height parents. Hand sizing to consumer CSS so
.flights-map-start__map height:500px wins.
2. FlightsMap /map/api/tile/{z}/{x}/{y}.jpeg requests fell through to
Modern.js SSR (HTML body). Dev proxy now forwards /map/* to the
test env via curl with image headers and binary-safe piping.
3. PopularRequestsPanel duplicate React key (Route-SVO-LED appears
twice in upstream). Suffix the key with the visible index.
4. OnlineBoardDetailsPage /onlineboard/details 400. Upstream expects
an ISO datetime (yyyy-MM-DDTHH:mm:ss), matching Angular's
ApiFormatterService.formatDate. Append T00:00:00.
5. Browser-level SignalR CORS errors on every details page: the
default SIGNALR_HUB_URL pointed at an unreachable placeholder.
Default to empty + skip the connection in useLiveFlights when
blank. Also configureLogging(LogLevel.None) so SignalR stops
writing its own negotiation failures to console. Live updates
re-enable by setting SIGNALR_HUB_URL on a deployment.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
* Port 8080 (browser-facing):
|
||||
* /api/* → curl → https://flights.test.aeroflot.ru (bypasses WAF via curl TLS)
|
||||
* /flights/* → curl → https://flights.test.aeroflot.ru
|
||||
* /map/* → curl → https://flights.test.aeroflot.ru (binary JPEG tiles)
|
||||
* /* → localhost:8081 (Modern.js SSR + HMR)
|
||||
*/
|
||||
import express from "express";
|
||||
@@ -58,6 +59,41 @@ app.get("/api/appSettings", (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// --- Tile proxy via curl (binary JPEG, pipe stdout straight to response) ---
|
||||
const TILE_CONTENT_TYPES = {
|
||||
".jpeg": "image/jpeg",
|
||||
".jpg": "image/jpeg",
|
||||
".png": "image/png",
|
||||
".webp": "image/webp",
|
||||
};
|
||||
app.use("/map", (req, res) => {
|
||||
const targetUrl = `${API_TARGET}${req.originalUrl}`;
|
||||
const ext = req.path.substring(req.path.lastIndexOf("."));
|
||||
const contentType = TILE_CONTENT_TYPES[ext] ?? "application/octet-stream";
|
||||
|
||||
res.status(200);
|
||||
res.setHeader("Content-Type", contentType);
|
||||
res.setHeader("Cache-Control", "public, max-age=86400");
|
||||
|
||||
const args = [
|
||||
"-sS",
|
||||
"-f", // fail on HTTP 4xx/5xx
|
||||
"-H", `Accept: image/webp,image/jpeg,image/*,*/*`,
|
||||
"-H", `User-Agent: ${req.headers["user-agent"] || "Mozilla/5.0"}`,
|
||||
"-H", `Referer: ${API_TARGET}/`,
|
||||
targetUrl,
|
||||
];
|
||||
const child = spawn("/usr/bin/curl", args, { stdio: ["ignore", "pipe", "pipe"] });
|
||||
|
||||
child.stdout.pipe(res);
|
||||
child.on("exit", (code) => {
|
||||
if (code !== 0) {
|
||||
// -f means upstream failed; close cleanly with empty body.
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// --- API proxy via curl (bypasses WAF TLS fingerprinting) ---
|
||||
app.use(["/api", "/flights"], (req, res) => {
|
||||
const targetUrl = `${API_TARGET}${req.originalUrl}`;
|
||||
|
||||
Reference in New Issue
Block a user