90 lines
3.3 KiB
Python
90 lines
3.3 KiB
Python
import base64
|
||
import json
|
||
import httpx
|
||
from fastapi import APIRouter, Request
|
||
from fastapi.responses import HTMLResponse, JSONResponse
|
||
from urllib.parse import quote_plus
|
||
|
||
WEBHOOK_DEBUG_URL = "https://n8n.clientright.ru/webhook/test"
|
||
|
||
router = APIRouter(prefix="/api/v1/debug", tags=["debug"])
|
||
|
||
|
||
@router.post("/forward-to-webhook")
|
||
async def forward_to_webhook(request: Request):
|
||
"""
|
||
Прокси: принимает JSON body и пересылает на n8n webhook (обход CORS с debug-webapp).
|
||
Сначала POST; если n8n вернёт 404 (webhook только GET) — повторяем GET с ?data=base64(body).
|
||
"""
|
||
try:
|
||
body = await request.json()
|
||
except Exception:
|
||
body = {}
|
||
async with httpx.AsyncClient(timeout=15.0) as client:
|
||
r = await client.post(WEBHOOK_DEBUG_URL, json=body)
|
||
if r.status_code == 404 and "POST" in (r.text or ""):
|
||
b64 = base64.urlsafe_b64encode(json.dumps(body, ensure_ascii=False).encode()).decode().rstrip("=")
|
||
r = await client.get(f"{WEBHOOK_DEBUG_URL}?data={quote_plus(b64)}")
|
||
ct = r.headers.get("content-type", "")
|
||
if "application/json" in ct:
|
||
try:
|
||
content = r.json()
|
||
except Exception:
|
||
content = {"status": r.status_code, "text": (r.text or "")[:500]}
|
||
else:
|
||
content = {"status": r.status_code, "text": (r.text or "")[:500]}
|
||
return JSONResponse(status_code=r.status_code, content=content)
|
||
|
||
|
||
@router.get("/set_session_redirect", response_class=HTMLResponse)
|
||
async def set_session_redirect(request: Request, session_token: str = "", claim_id: str = "", redirect_to: str = "/hello"):
|
||
"""
|
||
Temporary helper: returns an HTML page that sets localStorage.session_token and redirects to /hello?claim_id=...
|
||
Use for manual testing: open this URL in a browser on the target origin.
|
||
"""
|
||
# Ensure values are safe for embedding
|
||
js_session = session_token.replace('"', '\\"')
|
||
target_claim = quote_plus(claim_id) if claim_id else ""
|
||
# sanitize redirect_to - allow only absolute path starting with '/'
|
||
if not redirect_to.startswith('/'):
|
||
redirect_to = '/hello'
|
||
if target_claim:
|
||
# append query param correctly
|
||
if '?' in redirect_to:
|
||
redirect_url = f"{redirect_to}&claim_id={target_claim}"
|
||
else:
|
||
redirect_url = f"{redirect_to}?claim_id={target_claim}"
|
||
else:
|
||
redirect_url = redirect_to
|
||
|
||
html = f"""<!doctype html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8"/>
|
||
<title>Set session and redirect</title>
|
||
</head>
|
||
<body>
|
||
<script>
|
||
try {{
|
||
const token = "{js_session}";
|
||
if (token && token.length>0) {{
|
||
localStorage.setItem('session_token', token);
|
||
console.log('Set localStorage.session_token:', token);
|
||
}} else {{
|
||
console.log('No session_token provided');
|
||
}}
|
||
// give localStorage a tick then redirect
|
||
setTimeout(() => {{
|
||
window.location.href = "{redirect_url}";
|
||
}}, 200);
|
||
}} catch (e) {{
|
||
document.body.innerText = 'Error: ' + e;
|
||
}}
|
||
</script>
|
||
<p>Setting session and redirecting...</p>
|
||
<p>If you are not redirected, click <a id="go" href="{redirect_url}">here</a>.</p>
|
||
</body>
|
||
</html>"""
|
||
return HTMLResponse(content=html, status_code=200)
|
||
|