263 lines
9.7 KiB
HTML
263 lines
9.7 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Steam Auth Admin</title>
|
|
<link rel="stylesheet" href="/styles.css">
|
|
</head>
|
|
<body>
|
|
<header class="topbar">
|
|
<div class="title">
|
|
<h1>Steam auth admin</h1>
|
|
<div class="subline">
|
|
<span id="adminStatus" class="badge badge-muted">locked</span>
|
|
<a class="admin-link" href="/">Lobby list</a>
|
|
</div>
|
|
</div>
|
|
<div class="metrics" aria-label="Auth status">
|
|
<div class="metric wide">
|
|
<span class="metric-label">credentials</span>
|
|
<strong id="credentialsSource">-</strong>
|
|
</div>
|
|
<div class="metric wide">
|
|
<span class="metric-label">refresh token</span>
|
|
<strong id="tokenStatus">-</strong>
|
|
</div>
|
|
<div class="metric wide">
|
|
<span class="metric-label">steam</span>
|
|
<strong id="steamStatus">-</strong>
|
|
</div>
|
|
<div class="metric wide">
|
|
<span class="metric-label">game coordinator</span>
|
|
<strong id="gcStatus">-</strong>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="admin-main">
|
|
<section id="loginPanel" class="auth-panel">
|
|
<h2>Admin password</h2>
|
|
<div class="admin-grid">
|
|
<label>
|
|
<span>password</span>
|
|
<input id="adminPassword" type="password" autocomplete="current-password">
|
|
</label>
|
|
<div class="actions">
|
|
<button id="unlockBtn" class="primary" type="button">Unlock</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<p id="adminError" class="error" hidden></p>
|
|
<p id="adminMessage" class="notice" hidden></p>
|
|
|
|
<section id="notificationPanel" class="auth-panel" hidden>
|
|
<h2>Browser notifications</h2>
|
|
<p class="panel-copy">Push notifications work in the background. Production deployments must use HTTPS.</p>
|
|
<div class="actions left">
|
|
<button id="enableNotificationsBtn" class="primary" type="button">Enable on this browser</button>
|
|
<button id="disableNotificationsBtn" type="button">Disable on this browser</button>
|
|
<button id="testNotificationBtn" type="button">Send test</button>
|
|
<span id="notificationStatus" class="inline-status">checking</span>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="telegramPanel" class="auth-panel" hidden>
|
|
<h2>Telegram notifications</h2>
|
|
<p class="panel-copy">Create a bot with @BotFather. Each recipient must open the bot and send it a message before the bot can write to that numeric Telegram user ID. The token is stored only on the server and is never returned to this page.</p>
|
|
<div class="admin-grid">
|
|
<label>
|
|
<span>bot token</span>
|
|
<input id="telegramToken" type="password" autocomplete="off" placeholder="paste token or leave blank to keep saved token">
|
|
</label>
|
|
<label>
|
|
<span>Telegram user IDs, comma-separated</span>
|
|
<input id="telegramRecipientIds" type="text" inputmode="numeric" placeholder="123456789, 987654321">
|
|
</label>
|
|
</div>
|
|
<div class="actions left panel-actions">
|
|
<button id="saveTelegramBtn" class="primary" type="button">Save Telegram</button>
|
|
<button id="testTelegramBtn" type="button">Send test</button>
|
|
<button id="disableTelegramBtn" class="danger" type="button">Disable Telegram</button>
|
|
<span id="telegramStatus" class="inline-status">not configured</span>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="lobbyPanel" class="auth-panel" hidden>
|
|
<h2>Lobby automation</h2>
|
|
<p class="panel-copy">Player thresholds count real users only; the Steam bot itself is excluded. To avoid protocol-specific IDs, click <strong>Create template</strong> on a lobby in the lobby list and this form will be prefilled after admin authorization.</p>
|
|
<div class="lobby-grid">
|
|
<label>
|
|
<span>lobby name</span>
|
|
<input id="lobbyName" type="text" maxlength="100" placeholder="Long queue lobby">
|
|
</label>
|
|
<label>
|
|
<span>region</span>
|
|
<select id="lobbyRegion"></select>
|
|
</label>
|
|
<label>
|
|
<span>workshop ID</span>
|
|
<input id="customGameId" type="text" inputmode="numeric" placeholder="1234567890">
|
|
</label>
|
|
<label>
|
|
<span>internal addon name</span>
|
|
<input id="customGameMode" type="text" placeholder="copied by Create template">
|
|
</label>
|
|
<label>
|
|
<span>map name</span>
|
|
<input id="customMapName" type="text" placeholder="map_name">
|
|
</label>
|
|
<label>
|
|
<span>lobby password</span>
|
|
<input id="lobbyPassKey" type="text" autocomplete="off">
|
|
</label>
|
|
<label>
|
|
<span>custom min players</span>
|
|
<input id="customMinPlayers" type="number" min="1" max="64">
|
|
</label>
|
|
<label>
|
|
<span>custom max players</span>
|
|
<input id="customMaxPlayers" type="number" min="2" max="64">
|
|
</label>
|
|
<label>
|
|
<span>notify at real players</span>
|
|
<input id="notifyAtPlayers" type="number" min="1" max="64">
|
|
</label>
|
|
<label>
|
|
<span>bot leaves at real players</span>
|
|
<input id="leaveAtPlayers" type="number" min="1" max="64">
|
|
</label>
|
|
<label class="span-2">
|
|
<span>admin persona names or SteamID64, comma-separated</span>
|
|
<input id="adminNames" type="text" placeholder="Alice, Bob, 7656119...">
|
|
</label>
|
|
<label>
|
|
<span>custom game CRC (optional)</span>
|
|
<input id="customGameCrc" type="text" inputmode="numeric">
|
|
</label>
|
|
<label>
|
|
<span>workshop timestamp (optional)</span>
|
|
<input id="customGameTimestamp" type="text" inputmode="numeric">
|
|
</label>
|
|
<label class="check">
|
|
<input id="allowSpectating" type="checkbox" checked>
|
|
<span>allow spectating</span>
|
|
</label>
|
|
</div>
|
|
<div class="actions left panel-actions">
|
|
<button id="saveLobbySettingsBtn" type="button">Save settings</button>
|
|
<button id="createLobbyBtn" class="primary" type="button">Create lobby</button>
|
|
<button id="stopLobbyBtn" class="danger" type="button">Leave lobby</button>
|
|
</div>
|
|
<dl class="details lobby-details">
|
|
<div>
|
|
<dt>automation</dt>
|
|
<dd id="automationPhase">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>lobby ID</dt>
|
|
<dd id="activeLobbyId">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>real players</dt>
|
|
<dd id="activePlayerCount">0</dd>
|
|
</div>
|
|
<div>
|
|
<dt>lobby browser / password</dt>
|
|
<dd id="publicationStatus">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>arcade Play queue</dt>
|
|
<dd id="arcadePublicationStatus">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>GC lobby flags</dt>
|
|
<dd id="lobbyProtocolStatus">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Dota client version</dt>
|
|
<dd id="dotaClientVersion">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>leave reason</dt>
|
|
<dd id="leaveReason">-</dd>
|
|
</div>
|
|
</dl>
|
|
<div id="lobbyMembers" class="member-list muted">No active lobby members.</div>
|
|
</section>
|
|
|
|
<section id="credentialsPanel" class="auth-panel" hidden>
|
|
<h2>Steam credentials</h2>
|
|
<p class="panel-copy">Passwords, per-account refresh tokens, and Steam Guard machine authorization are stored on the server. Switching accounts reconnects Steam and Dota without restarting this process; leave an active lobby first.</p>
|
|
<div class="admin-grid">
|
|
<label>
|
|
<span>saved accounts</span>
|
|
<select id="savedSteamAccount"></select>
|
|
</label>
|
|
<div class="actions">
|
|
<button id="activateAccountBtn" type="button">Activate selected</button>
|
|
</div>
|
|
<label>
|
|
<span>account</span>
|
|
<input id="steamAccount" type="text" autocomplete="username">
|
|
</label>
|
|
<label>
|
|
<span>password</span>
|
|
<input id="steamPassword" type="password" autocomplete="current-password" placeholder="leave blank to keep the saved password">
|
|
</label>
|
|
<label class="check">
|
|
<input id="clearToken" type="checkbox">
|
|
<span>forget cached refresh token for this account</span>
|
|
</label>
|
|
<div class="actions">
|
|
<button id="reloadBtn" type="button">Reload</button>
|
|
<button id="saveBtn" class="primary" type="button">Save and activate</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="guardPanel" class="auth-panel" hidden>
|
|
<h2>Steam Guard</h2>
|
|
<div class="admin-grid">
|
|
<label>
|
|
<span>code</span>
|
|
<input id="steamGuardCode" type="text" autocomplete="one-time-code" inputmode="numeric">
|
|
</label>
|
|
<div class="actions">
|
|
<button id="submitGuardBtn" class="primary" type="button">Submit code</button>
|
|
</div>
|
|
</div>
|
|
<p id="guardHint" class="hint"></p>
|
|
</section>
|
|
|
|
<section id="tokenPanel" class="auth-panel" hidden>
|
|
<h2>Saved token</h2>
|
|
<dl class="details">
|
|
<div>
|
|
<dt>SteamID</dt>
|
|
<dd id="tokenSteamId">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Account</dt>
|
|
<dd id="tokenAccount">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Updated</dt>
|
|
<dd id="tokenUpdated">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Expires</dt>
|
|
<dd id="tokenExpires">-</dd>
|
|
</div>
|
|
</dl>
|
|
<div class="actions left">
|
|
<button id="clearTokenBtn" type="button">Clear refresh token</button>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<script src="/admin.js"></script>
|
|
</body>
|
|
</html>
|