Let 3x-ui assign inbound and share link on create.
Stop requiring inbound selection in the site UI; send the create request to the chosen panel and use the link it returns. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3909,6 +3909,7 @@ async def api_add_user_connection(request: Request, user_id: str, req: AddUserCo
|
||||
created = await xui_create_vless_config(
|
||||
data.get('settings', {}),
|
||||
name=req.name or user.get('username') or 'user',
|
||||
# Optional hint only — panel assigns inbound + share link
|
||||
inbound_id=req.xui_inbound_id or panel.get('default_inbound_id') or None,
|
||||
panel_id=panel_id,
|
||||
)
|
||||
@@ -4490,8 +4491,6 @@ async def _create_config_for_protocol(
|
||||
"""Create VPN client; returns {client_id, config, subscription_url, protocol, server_id}."""
|
||||
protocol = protocol or 'xui'
|
||||
if protocol_base(protocol) == 'xui':
|
||||
if not xui_inbound_id:
|
||||
raise RuntimeError('Select a VLESS inbound for this invite link')
|
||||
from managers.xui_api import xui_create_vless_config
|
||||
from managers.xui_servers import get_xui_server, ensure_xui_servers
|
||||
ensure_xui_servers(data.get('settings') or {})
|
||||
@@ -4499,11 +4498,13 @@ async def _create_config_for_protocol(
|
||||
if not panel:
|
||||
raise RuntimeError('Add a 3x-ui server in Settings first')
|
||||
panel_id = panel.get('id') or ''
|
||||
# Prefer invite/default inbound; otherwise 3x-ui picks first VLESS on that panel
|
||||
inbound = xui_inbound_id or panel.get('default_inbound_id') or None
|
||||
expiry_ms = _expiry_ms_from_duration_days(duration_days)
|
||||
created = await xui_create_vless_config(
|
||||
data.get('settings', {}),
|
||||
name=name,
|
||||
inbound_id=xui_inbound_id,
|
||||
inbound_id=inbound,
|
||||
expiry_time=expiry_ms,
|
||||
panel_id=panel_id,
|
||||
)
|
||||
@@ -4515,6 +4516,7 @@ async def _create_config_for_protocol(
|
||||
'protocol': 'xui',
|
||||
'server_id': 0,
|
||||
'xui_panel_id': panel_id,
|
||||
'xui_inbound_id': int(created.get('inbound_id') or 0),
|
||||
'expires_at': (
|
||||
datetime.fromtimestamp(expiry_ms / 1000).isoformat()
|
||||
if expiry_ms > 0 else None
|
||||
@@ -4609,10 +4611,9 @@ async def api_create_invite(request: Request, req: InviteCreateRequest):
|
||||
if not panel:
|
||||
return JSONResponse({'error': 'Add a 3x-ui server in Settings first'}, status_code=400)
|
||||
panel_id = panel.get('id') or ''
|
||||
# Inbound is optional — 3x-ui panel assigns it (or uses server default) on redeem
|
||||
if not inbound_id:
|
||||
inbound_id = int(panel.get('default_inbound_id') or 0)
|
||||
if not inbound_id:
|
||||
return JSONResponse({'error': 'Select a VLESS inbound'}, status_code=400)
|
||||
link = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'name': (req.name or 'Invite').strip() or 'Invite',
|
||||
@@ -4677,9 +4678,14 @@ async def api_update_invite(request: Request, invite_id: str, req: InviteUpdateR
|
||||
link['enabled'] = bool(req.enabled)
|
||||
if req.reset_used:
|
||||
link['used_count'] = 0
|
||||
# Validate inbound for xui
|
||||
if protocol_base(link.get('protocol') or 'xui') == 'xui' and not int(link.get('xui_inbound_id') or 0):
|
||||
return JSONResponse({'error': 'Select a VLESS inbound'}, status_code=400)
|
||||
if protocol_base(link.get('protocol') or 'xui') == 'xui':
|
||||
from managers.xui_servers import get_xui_server, ensure_xui_servers
|
||||
ensure_xui_servers(data.setdefault('settings', {}))
|
||||
panel = get_xui_server(data.get('settings') or {}, link.get('xui_panel_id') or None)
|
||||
if not panel:
|
||||
return JSONResponse({'error': 'Add a 3x-ui server in Settings first'}, status_code=400)
|
||||
if not link.get('xui_panel_id'):
|
||||
link['xui_panel_id'] = panel.get('id') or ''
|
||||
save_data(data)
|
||||
return {'status': 'success', 'invite': _invite_public_view(link)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user