Compare commits
2 Commits
a81869c96d
...
be36cefd4b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be36cefd4b | ||
|
|
9635b00e07 |
@ -53,7 +53,7 @@ function getFirstAvailableId(ids: number[]) : number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generateNodeData(nodes : NodeData[]) : NodeData | null {
|
function generateNodeData(nodes : NodeData[]) : NodeData | null {
|
||||||
const hostId = getFirstAvailableId(nodes.map(n => n.hostId))
|
const hostId = getFirstAvailableId(nodes.filter(n => n.groupId == 0).map(n => n.hostId))
|
||||||
if(hostId > 255) return null
|
if(hostId > 255) return null
|
||||||
|
|
||||||
const privateKey = generateWireGuardPrivateKey();
|
const privateKey = generateWireGuardPrivateKey();
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useState, ReactNode } from 'react';
|
import { useState, ReactNode } from 'react';
|
||||||
import { NodeData, Settings } from '../types/graph';
|
import { NodeData, Settings } from '../types/graph';
|
||||||
|
import { generateWireGuardPrivateKey } from '../utils/wireguardConfig'
|
||||||
import './NodeEditor.css';
|
import './NodeEditor.css';
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +40,10 @@ export default function NodeEditor({
|
|||||||
// onClose();
|
// onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleGenerateKey = (): void => {
|
||||||
|
handleInputChange('privateKey', generateWireGuardPrivateKey())
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="node-editor-overlay">
|
<div className="node-editor-overlay">
|
||||||
<div className="node-editor">
|
<div className="node-editor">
|
||||||
@ -70,21 +75,80 @@ export default function NodeEditor({
|
|||||||
<div className="item-group">
|
<div className="item-group">
|
||||||
<input
|
<input
|
||||||
value={formData.privateKey || ''}
|
value={formData.privateKey || ''}
|
||||||
onChange={(e) => handleInputChange('privateKey', e.target.value)}
|
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
<button className="btn-interect">重新生成</button>
|
<button className="btn-interect" onClick={handleGenerateKey}>重新生成</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>侦听端口</label>
|
<label>主机ID</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
|
min="0"
|
||||||
|
max="255"
|
||||||
|
step="1"
|
||||||
|
value={formData.hostId}
|
||||||
|
onChange={(e) => handleInputChange('hostId', e.target.value)}
|
||||||
|
placeholder="同一子网ID下主机ID不能重复,不得超过255"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>子网ID</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
max="255"
|
||||||
|
step="1"
|
||||||
|
value={formData.groupId}
|
||||||
|
onChange={(e) => handleInputChange('groupId', e.target.value)}
|
||||||
|
placeholder="不得超过255"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* host options */}
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>PostUp (可选)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={formData.postUp || ''}
|
||||||
|
onChange={(e) => handleInputChange('postUp', e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>PostDown (可选)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={formData.postDown || ''}
|
||||||
|
onChange={(e) => handleInputChange('postDown', e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>mtu (可选)</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
step="1"
|
||||||
|
value={formData.mtu || ''}
|
||||||
|
onChange={(e) => handleInputChange('mtu', e.target.value)}
|
||||||
|
placeholder={settings.mtu ? `默认值:${settings.mtu}` : ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label>侦听端口 (可选)</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="1024"
|
||||||
|
max="49151"
|
||||||
|
step="1"
|
||||||
value={formData.listenPort || ''}
|
value={formData.listenPort || ''}
|
||||||
onChange={(e) => handleInputChange('listenPort', e.target.value)}
|
onChange={(e) => handleInputChange('listenPort', e.target.value)}
|
||||||
placeholder="例如: 51820"
|
placeholder={`默认值:${settings.listenPort}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -94,17 +158,16 @@ export default function NodeEditor({
|
|||||||
type="text"
|
type="text"
|
||||||
value={formData.dnsServers || ''}
|
value={formData.dnsServers || ''}
|
||||||
onChange={(e) => handleInputChange('dnsServers', e.target.value)}
|
onChange={(e) => handleInputChange('dnsServers', e.target.value)}
|
||||||
placeholder="例如: 8.8.8.8"
|
placeholder="例如: 8.8.8.8,1.1.1.1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>持久保活 (可选)</label>
|
<label>备注 (可选)</label>
|
||||||
<input
|
<textarea
|
||||||
type="number"
|
rows={3}
|
||||||
value={formData.persistentKeepalive || ''}
|
value={formData.notes || ''}
|
||||||
onChange={(e) => handleInputChange('persistentKeepalive', e.target.value)}
|
onChange={(e) => handleInputChange('notes', e.target.value)}
|
||||||
placeholder="秒数"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,23 @@ export type AppNode = Node<NodeData>;
|
|||||||
|
|
||||||
export type AppEdge = Edge<EdgeData>;
|
export type AppEdge = Edge<EdgeData>;
|
||||||
|
|
||||||
|
export interface GroupAllowRule {
|
||||||
|
kind: 'group'
|
||||||
|
allowGroup: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HostAllowRule {
|
||||||
|
kind: 'host'
|
||||||
|
allowHost: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomAllowRule {
|
||||||
|
kind: 'custom'
|
||||||
|
allow: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AllowRule = GroupAllowRule | HostAllowRule | CustomAllowRule
|
||||||
|
|
||||||
export type NodeData = {
|
export type NodeData = {
|
||||||
// basic
|
// basic
|
||||||
label: string;
|
label: string;
|
||||||
@ -11,27 +28,28 @@ export type NodeData = {
|
|||||||
groupId: number;
|
groupId: number;
|
||||||
hostId: number;
|
hostId: number;
|
||||||
|
|
||||||
// options
|
// host options
|
||||||
postUp?: string;
|
postUp?: string;
|
||||||
postDown?: string;
|
postDown?: string;
|
||||||
persistentKeepalive?: string;
|
|
||||||
dnsServers?: string;
|
|
||||||
disallowSubnet?: string;
|
|
||||||
allowIPs?: string;
|
|
||||||
mtu?: number;
|
mtu?: number;
|
||||||
listenPort?: number;
|
|
||||||
notes?: string;
|
notes?: string;
|
||||||
}
|
listenPort?: number;
|
||||||
|
dnsServers?: string;
|
||||||
|
|
||||||
export type EdgeData = {
|
// peer options
|
||||||
isTwoWayEdge: boolean
|
// allowRules?: AllowRule[];
|
||||||
|
// persistentKeepalive?: string; todo: 加到边上
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Settings = {
|
export type Settings = {
|
||||||
v4SubNetPrefix: [number, number];
|
v4SubNetPrefix: [number, number];
|
||||||
listenPort: number;
|
listenPort: number;
|
||||||
|
|
||||||
// global options
|
// options
|
||||||
v6SubNetPrefix?: [string, string, string, string];
|
v6SubNetPrefix?: [string, string, string, string];
|
||||||
mtu?: number;
|
mtu?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type EdgeData = {
|
||||||
|
isTwoWayEdge: boolean
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user