diff --git a/Dockerfile b/Dockerfile
index 6310d47..a0f5a47 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,6 +3,7 @@ WORKDIR /app
COPY api/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY api/app/ ./app/
+COPY api/static/ ./static/ # <-- Add this line
RUN mkdir -p /data
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
\ No newline at end of file
diff --git a/api/app/auth.py b/api/app/auth.py
index c8f3109..9ac44b6 100644
--- a/api/app/auth.py
+++ b/api/app/auth.py
@@ -14,6 +14,8 @@ def get_db():
conn.row_factory = sqlite3.Row
return conn
+# your-very-long-random-admin-key
+
def init_db():
conn = get_db()
conn.execute("""
diff --git a/api/app/main.py b/api/app/main.py
index 4e6dc24..ef83de5 100644
--- a/api/app/main.py
+++ b/api/app/main.py
@@ -1,23 +1,31 @@
from fastapi import FastAPI, HTTPException, Depends, Header, Query, Request
-from fastapi.responses import JSONResponse
-from .auth import init_db, verify_api_key, get_db # make sure auth.py exports get_db
+from fastapi.responses import JSONResponse, FileResponse
+from fastapi.security import HTTPBasic, HTTPBasicCredentials
+from .auth import init_db, verify_api_key, get_db
from .models import Event, BatchEvents
from .enrichment import enrich_event
from .influx import write_event, client, INFLUX_ORG, INFLUX_BUCKET
import logging
import os
import secrets
-import datetime
+import pathlib
logging.basicConfig(level=logging.INFO)
# Environment variables
-ADMIN_API_KEY = os.getenv("ADMIN_API_KEY", "admin-secret-change-me")
+ADMIN_USERNAME = os.getenv("ADMIN_USERNAME", "admin")
+ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD", "admin") # change in pod YAML!
-# Initialise database (creates table if missing)
init_db()
-
app = FastAPI(title="Signal - Roblox Telemetry")
+security = HTTPBasic()
+
+# ---------- HTTP Basic auth dependency ----------
+def require_admin(credentials: HTTPBasicCredentials = Depends(security)):
+ if credentials.username != ADMIN_USERNAME or credentials.password != ADMIN_PASSWORD:
+ raise HTTPException(status_code=401, detail="Invalid credentials",
+ headers={"WWW-Authenticate": "Basic"})
+ return True
# ---------- Original endpoints ----------
@app.get("/health")
@@ -35,11 +43,12 @@ async def ingest_event(payload: Event | BatchEvents, game: str = Depends(verify_
write_event(enriched)
return {"success": True}
-# ---------- Admin authentication helper ----------
-def require_admin(x_admin_key: str = Header(None)):
- if not x_admin_key or x_admin_key != ADMIN_API_KEY:
- raise HTTPException(status_code=403, detail="Forbidden")
- return True
+# ---------- Serve the admin HTML ----------
+STATIC_DIR = pathlib.Path(__file__).parent.parent / "static"
+
+@app.get("/admin", include_in_schema=False)
+async def admin_page(admin: bool = Depends(require_admin)):
+ return FileResponse(STATIC_DIR / "index.html")
# ---------- Admin: API Keys ----------
@app.get("/admin/keys")
diff --git a/api/static/index.html b/api/static/index.html
new file mode 100644
index 0000000..5c3a391
--- /dev/null
+++ b/api/static/index.html
@@ -0,0 +1,142 @@
+
+
+
+
+ RBXLogger Admin
+
+
+
+ RBXLogger Admin
+
+
+
+
+
+
+
+
+
Create new key
+
+
+
+
+ | Key | Game | Active | Created | Actions |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file