Skip to content

Commit aa14ee3

Browse files
rohoswaggerclaude
andcommitted
fix(craft): simplify offline page and remove dead /_next/ route
- Offline HTML: drop typing animation, show single static message "Sandbox is asleep..." with the terminal chrome from page.tsx - Remove nextjs_assets_router and _extract_session_from_referer: _rewrite_asset_paths() already rewrites all /_next/ references to /build/sessions/{session_id}/webapp/_next/ in proxied responses, so the root-level /_next/ route was never hit. Removing it eliminates Referer-based session extraction (broken when header is absent) and an unnecessary public endpoint bypass in auth_check.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent ce69c91 commit aa14ee3

File tree

3 files changed

+5
-129
lines changed

3 files changed

+5
-129
lines changed

backend/onyx/main.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
from onyx.server.documents.credential import router as credential_router
6565
from onyx.server.documents.document import router as document_router
6666
from onyx.server.documents.standard_oauth import router as standard_oauth_router
67-
from onyx.server.features.build.api.api import nextjs_assets_router
6867
from onyx.server.features.build.api.api import public_build_router
6968
from onyx.server.features.build.api.api import router as build_router
7069
from onyx.server.features.default_assistant.api import (
@@ -381,7 +380,6 @@ def get_application(lifespan_override: Lifespan | None = None) -> FastAPI:
381380
include_router_with_global_prefix_prepended(application, projects_router)
382381
include_router_with_global_prefix_prepended(application, public_build_router)
383382
include_router_with_global_prefix_prepended(application, build_router)
384-
include_router_with_global_prefix_prepended(application, nextjs_assets_router)
385383
include_router_with_global_prefix_prepended(application, document_set_router)
386384
include_router_with_global_prefix_prepended(application, hierarchy_router)
387385
include_router_with_global_prefix_prepended(application, search_settings_router)

backend/onyx/server/auth_check.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
# craft webapp proxy — public when session.is_public=True (access enforced in handler)
6363
("/build/sessions/{session_id}/webapp", {"GET"}),
6464
("/build/sessions/{session_id}/webapp/{path:path}", {"GET"}),
65-
("/_next/{path:path}", {"GET"}),
6665
]
6766

6867

backend/onyx/server/features/build/api/api.py

Lines changed: 5 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -420,15 +420,13 @@ def _offline_html_response() -> Response:
420420
padding: 2rem;
421421
}
422422
423-
/* Terminal window */
424423
.terminal {
425424
width: 100%;
426425
max-width: 580px;
427426
border: 2px solid #374151;
428427
border-radius: 2px;
429428
}
430429
431-
/* Title bar */
432430
.titlebar {
433431
background: #1f2937;
434432
padding: 0.5rem 0.75rem;
@@ -438,7 +436,6 @@ def _offline_html_response() -> Response:
438436
border-bottom: 1px solid #374151;
439437
}
440438
441-
/* Square traffic-light buttons (not circles) */
442439
.btn { width: 12px; height: 12px; border-radius: 2px; flex-shrink: 0; }
443440
.btn-red { background: #ef4444; }
444441
.btn-yellow { background: #eab308; }
@@ -449,47 +446,22 @@ def _offline_html_response() -> Response:
449446
text-align: center;
450447
font-size: 0.75rem;
451448
color: #6b7280;
452-
margin-right: 36px; /* offset for buttons width so label is visually centred */
449+
margin-right: 36px;
453450
}
454451
455-
/* Terminal body */
456452
.body {
457453
background: #111827;
458454
padding: 1.5rem;
459455
min-height: 200px;
460456
font-size: 0.875rem;
461457
color: #d1d5db;
462-
}
463-
464-
/* History lines (completed) */
465-
.history { margin-bottom: 0.25rem; }
466-
.history .prompt { color: #10b981; }
467-
.history .text { color: #6b7280; }
468-
469-
/* Active typing line */
470-
.active {
471458
display: flex;
472-
align-items: center;
459+
align-items: flex-start;
473460
gap: 0.375rem;
474461
}
462+
475463
.prompt { color: #10b981; user-select: none; }
476-
#typed { color: #d1d5db; }
477-
478-
/* Block cursor */
479-
.cursor {
480-
display: inline-block;
481-
width: 8px;
482-
height: 1.1em;
483-
background: #10b981;
484-
vertical-align: text-bottom;
485-
animation: blink 1s step-start infinite;
486-
}
487-
@keyframes blink {
488-
0%, 100% { opacity: 1; }
489-
50% { opacity: 0; }
490-
}
491464
492-
/* Tagline */
493465
.tagline {
494466
font-size: 0.8125rem;
495467
color: #4b5563;
@@ -506,61 +478,11 @@ def _offline_html_response() -> Response:
506478
<span class="title-label">crafting_table</span>
507479
</div>
508480
<div class="body">
509-
<div id="history"></div>
510-
<div class="active">
511-
<span class="prompt">/&gt;</span>
512-
<span id="typed"></span><span class="cursor"></span>
513-
</div>
481+
<span class="prompt">/&gt;</span>
482+
<span>Sandbox is asleep...</span>
514483
</div>
515484
</div>
516485
<p class="tagline">Ask the owner to open their Craft session to wake it up.</p>
517-
518-
<script>
519-
var messages = [
520-
"Sandbox is asleep...",
521-
"Waiting for owner to wake it up...",
522-
"Ask the owner to open their Craft session.",
523-
"This page will refresh automatically.",
524-
"/status: idle"
525-
];
526-
527-
var msgIndex = 0;
528-
var charIndex = 0;
529-
var typedEl = document.getElementById("typed");
530-
var historyEl = document.getElementById("history");
531-
var HISTORY_MAX = 3;
532-
var history = [];
533-
534-
function addHistory(text) {
535-
history.push(text);
536-
if (history.length > HISTORY_MAX) history.shift();
537-
historyEl.innerHTML = history.map(function(t) {
538-
return '<div class="history"><span class="prompt">/&gt; </span><span class="text">' +
539-
t.replace(/&/g,"&amp;").replace(/</g,"&lt;") + "</span></div>";
540-
}).join("");
541-
}
542-
543-
function typeChar() {
544-
var msg = messages[msgIndex];
545-
if (charIndex < msg.length) {
546-
typedEl.textContent += msg[charIndex];
547-
charIndex++;
548-
setTimeout(typeChar, 55 + Math.random() * 40);
549-
} else {
550-
setTimeout(nextMessage, 1600);
551-
}
552-
}
553-
554-
function nextMessage() {
555-
addHistory(messages[msgIndex]);
556-
msgIndex = (msgIndex + 1) % messages.length;
557-
charIndex = 0;
558-
typedEl.textContent = "";
559-
setTimeout(typeChar, 300);
560-
}
561-
562-
typeChar();
563-
</script>
564486
</body>
565487
</html>"""
566488
return Response(content=html, status_code=503, media_type="text/html")
@@ -616,49 +538,6 @@ def get_webapp_path(
616538
raise
617539

618540

619-
# Separate router for Next.js static assets at /_next/*
620-
# This is needed because Next.js apps may reference assets with root-relative paths
621-
# that don't get rewritten. The session_id is extracted from the Referer header.
622-
nextjs_assets_router = APIRouter()
623-
624-
625-
def _extract_session_from_referer(request: Request) -> UUID | None:
626-
"""Extract session_id from the Referer header.
627-
628-
Expects Referer to contain /api/build/sessions/{session_id}/webapp
629-
"""
630-
import re
631-
632-
referer = request.headers.get("referer", "")
633-
match = re.search(r"/api/build/sessions/([a-f0-9-]+)/webapp", referer)
634-
if match:
635-
try:
636-
return UUID(match.group(1))
637-
except ValueError:
638-
return None
639-
return None
640-
641-
642-
@nextjs_assets_router.get("/_next/{path:path}", response_model=None)
643-
def get_nextjs_assets(
644-
path: str,
645-
request: Request,
646-
user: User | None = Depends(optional_user),
647-
db_session: Session = Depends(get_session),
648-
) -> StreamingResponse | Response:
649-
"""Proxy Next.js static assets at root /_next/ path.
650-
Session is determined from the Referer header.
651-
"""
652-
session_id = _extract_session_from_referer(request)
653-
if not session_id:
654-
raise HTTPException(
655-
status_code=400,
656-
detail="Could not determine session from request context",
657-
)
658-
_check_webapp_access(session_id, user, db_session)
659-
return _proxy_request(f"_next/{path}", request, session_id, db_session)
660-
661-
662541
# =============================================================================
663542
# Sandbox Management Endpoints
664543
# =============================================================================

0 commit comments

Comments
 (0)