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)
|
|||
|
|
|