feat: manual landing endpoints for forward nodes (item 8)
A forward node's exit target is now a choice: a managed panel server (existing behavior) or a manual landing endpoint — address + port + protocol (VLESS / SS2022 / SOCKS5) + operator-supplied credentials, including third-party nodes the panel does not run. The panel only builds the entry-side sing-box outbound and route rule; there is no exit resource, no exit job, and the node is exit-ready by definition. - model: Node.ExitMode/ExitAddress; manual exits force fixed port mode and skip the exit-server port table entirely - validation: address/port required; per-protocol credential presence; SS2022 passwords must be base64 key material of the method's key length (one PSK segment or serverKey:userKey) — the exact form sing-box accepts, rejected up front instead of failing at deploy - orchestration: resource building, deploy validation and rebuilds all branch on manualExit; switching managed->manual queues removal of the old exit resource, manual->managed mints a fresh exit resource id (deploy validation previously dereferenced the nil exit server — regression test locks the fix) - UI: exit target segmented control, link paste box that parses vless:// / ss:// / socks5:// links into the form, per-protocol credential fields (blank keeps the stored value on edit) - golden: new manualCreate/manualAssign/manualDeploy/manualJobs/ manualNodes sections — exactly one entry-side job whose outbound targets the manual address; all prior sections unchanged - the generated combined sing-box config passes the real sing-box 1.13.21 check
This commit is contained in:
+14
-7
@@ -703,13 +703,20 @@ func (m MeteredTraffic) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ServerID string `json:"serverId"`
|
||||
ExitServerID *string `json:"exitServerId"`
|
||||
Protocol string `json:"protocol"`
|
||||
Topology string `json:"topology"`
|
||||
ExitProtocol *string `json:"exitProtocol"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ServerID string `json:"serverId"`
|
||||
ExitServerID *string `json:"exitServerId"`
|
||||
Protocol string `json:"protocol"`
|
||||
Topology string `json:"topology"`
|
||||
ExitProtocol *string `json:"exitProtocol"`
|
||||
// ExitMode selects the forward exit target: "" / "managed" is a panel
|
||||
// server (ExitServerID); "manual" is an unmanaged landing endpoint
|
||||
// described by ExitAddress + ExitPort + ExitProtocol + ExitCredentials
|
||||
// (round-2 item 8). Manual exits have no exit resource and are always
|
||||
// ExitReady — the panel only builds the entry-side outbound.
|
||||
ExitMode string `json:"exitMode,omitempty"`
|
||||
ExitAddress string `json:"exitAddress,omitempty"`
|
||||
NetworkMode string `json:"networkMode"`
|
||||
RealityServerName string `json:"realityServerName"`
|
||||
RealityDestPort int `json:"realityDestPort"`
|
||||
|
||||
Reference in New Issue
Block a user