Files
BetiX/app/Http/Controllers/EmbedController.php
Dolo 0280278978
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Initialer Laravel Commit für BetiX
2026-04-04 18:01:50 +02:00

131 lines
6.0 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class EmbedController extends Controller
{
/**
* Show embedded game page.
*
* Requirement: For the Localhost provider (and generally safe),
* the URL must contain a `?mode=demo` or `?mode=real` query param
* so the correct mode is selected. If missing/invalid, we redirect
* to the same URL with a normalized `mode` parameter.
*/
public function show(Request $request, string $slug)
{
$rawMode = $request->query('mode');
$normalized = null;
if (is_string($rawMode)) {
$val = strtolower(trim($rawMode));
if (in_array($val, ['demo', 'real'], true)) {
$normalized = $val;
}
}
// If mode is missing or invalid → redirect to add/fix it (default demo)
if ($normalized === null) {
$normalized = 'demo';
$query = array_merge($request->query(), ['mode' => $normalized]);
$url = $request->url() . (empty($query) ? '' : ('?' . http_build_query($query)));
return redirect()->to($url, 302);
}
// Localhost provider integration for specific games
$slugKey = strtolower($slug);
$supported = [
'dice' => 'dice',
'plinko' => 'plinko',
'mines' => 'mines',
];
$base = rtrim((string) config('games.providers.local.base_url', 'http://localhost:3001/games'), '/');
if (array_key_exists($slugKey, $supported)) {
$gamePath = $supported[$slugKey];
$src = $base . '/' . $gamePath . '/index.html?mode=' . urlencode($normalized);
$title = htmlspecialchars("Local Provider • {$slug} ({$normalized})", ENT_QUOTES, 'UTF-8');
$srcAttr = htmlspecialchars($src, ENT_QUOTES, 'UTF-8');
$slugJson = json_encode($slug, JSON_UNESCAPED_SLASHES);
$modeJson = json_encode($normalized);
$srcJson = json_encode($src, JSON_UNESCAPED_SLASHES);
$html = <<<HTML
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{$title}</title>
<style>
html,body{margin:0;height:100%;background:#000}
.frame{position:fixed;inset:0;border:0;width:100%;height:100%;display:block;background:#000}
.bar{position:fixed;left:0;right:0;top:0;height:42px;background:#0b0b0b;border-bottom:1px solid #161616;display:flex;align-items:center;gap:10px;padding:0 12px;color:#d7d7d7;font:14px/1.2 system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif}
.sp{flex:1}
.pill{background:#131313;border:1px solid #1f1f1f;border-radius:999px;padding:6px 10px;color:#bbb}
</style>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; frame-src 'self' http://localhost:3001 http://127.0.0.1:3001; script-src 'self' 'unsafe-inline' http://localhost:3001 http://127.0.0.1:3001; connect-src *; img-src * data: blob:; style-src 'self' 'unsafe-inline' http://localhost:3001 http://127.0.0.1:3001; media-src *;" />
</head>
<body>
<div class="bar">
<div>Localhost Provider</div>
<div class="pill">Slug: {$slugKey}</div>
<div class="pill">Mode: {$normalized}</div>
<div class="sp"></div>
<div style="opacity:.6">src: {$srcAttr}</div>
</div>
<iframe class="frame" src="{$srcAttr}" allowfullscreen></iframe>
<script>
try { window.parent && window.parent.postMessage({ type: 'casino.embed.ready', provider: 'localhost', slug: {$slugJson}, mode: {$modeJson}, src: {$srcJson} }, '*'); } catch (e) {}
</script>
</body>
</html>
HTML;
return new Response($html, 200, ['Content-Type' => 'text/html; charset=utf-8']);
}
// Fallback minimal HTML placeholder for unknown slugs
$slugJson = json_encode($slug, JSON_UNESCAPED_SLASHES);
$modeJson = json_encode($normalized);
$html = <<<HTML
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Game Embed • {$slug} ({$normalized})</title>
<style>
:root{color-scheme:dark light}
body{margin:0;background:#0b0b0b;color:#e8e8e8;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif}
.wrap{min-height:100vh;display:grid;place-items:center}
.card{background:#0f0f0f;border:1px solid #1b1b1b;border-radius:12px;padding:24px;max-width:840px;width:92%}
h1{margin:0 0 8px;font-size:20px}
.muted{opacity:.7}
code{background:#121212;border:1px solid #1e1e1e;padding:.1em .35em;border-radius:6px}
</style>
</head>
<body>
<div class="wrap">
<div class="card">
<h1>Embedded Game (Fallback)</h1>
<p>Unbekannter Slug: <code>{$slug}</code></p>
<p>Mode: <code>{$normalized}</code></p>
<p class="muted">Unterstützte lokale Spiele: <code>dice</code>, <code>plinko</code>, <code>mines</code>. Bitte URL prüfen.</p>
</div>
</div>
<script>
try {
window.parent && window.parent.postMessage({ type: 'casino.embed.ready', slug: {$slugJson}, mode: {$modeJson} }, '*');
} catch {}
</script>
</body>
</html>
HTML;
return new Response($html, 200, ['Content-Type' => 'text/html; charset=utf-8']);
}
}