mirror of
https://github.com/liamcottle/reticulum-meshchat.git
synced 2026-04-28 00:20:48 +00:00
initial support for adding tcp interfaces
This commit is contained in:
parent
32c6bbf924
commit
8d8198b5f8
2 changed files with 161 additions and 4 deletions
|
|
@ -687,6 +687,13 @@
|
|||
<div class="ml-2">Reticulum WebChat must be restarted for any interface changes to take effect.</div>
|
||||
</div>
|
||||
|
||||
<button @click="tab = 'interfaces.add'" type="button" class="my-auto inline-flex items-center gap-x-1 rounded-md bg-gray-500 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||||
</svg>
|
||||
<span>Add Interface</span>
|
||||
</button>
|
||||
|
||||
<!-- interface list -->
|
||||
<div v-for="(iface, interface_name) of interfaces" class="border rounded bg-white shadow overflow-hidden">
|
||||
|
||||
|
|
@ -728,7 +735,7 @@
|
|||
</span>
|
||||
|
||||
<!-- tcp client interface -->
|
||||
<span v-if="iface.type === 'TCPClientInterface'">
|
||||
<span v-else-if="iface.type === 'TCPClientInterface'">
|
||||
{{ iface.type }} • {{ iface.target_host }}:{{ iface.target_port }}
|
||||
</span>
|
||||
|
||||
|
|
@ -798,6 +805,51 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- add interface tab -->
|
||||
<div v-if="tab === 'interfaces.add'" class="overflow-y-auto p-2 space-y-2">
|
||||
|
||||
<!-- add interface form -->
|
||||
<div class="bg-white rounded shadow divide-y divide-gray-200">
|
||||
<div class="p-2 font-bold">Add Interface</div>
|
||||
<div class="p-2 space-y-3">
|
||||
|
||||
<!-- interface name -->
|
||||
<div>
|
||||
<label class="block mb-2 text-sm font-medium text-gray-900">Name</label>
|
||||
<input type="text" placeholder="New Interface Name" v-model="newInterfaceName" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||
</div>
|
||||
|
||||
<!-- interface type -->
|
||||
<div class="mb-2">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-900">Type</label>
|
||||
<select v-model="newInterfaceType" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||
<option value="AutoInterface">AutoInterface</option>
|
||||
<option value="TCPClientInterface">TCPClientInterface</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- interface target host -->
|
||||
<div v-if="newInterfaceType === 'TCPClientInterface'" class="mb-2">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-900">Target Host</label>
|
||||
<input type="text" placeholder="example.com" v-model="newInterfaceTargetHost" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||
</div>
|
||||
|
||||
<!-- interface target port -->
|
||||
<div v-if="newInterfaceType === 'TCPClientInterface'" class="mb-2">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-900">Target Port</label>
|
||||
<input type="text" placeholder="1234" v-model="newInterfaceTargetPort" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||
</div>
|
||||
|
||||
<!-- add button -->
|
||||
<button @click="addInterface" type="button" class="bg-green-500 hover:bg-green-400 focus-visible:outline-green-500 my-auto inline-flex items-center gap-x-1 rounded-md p-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2">
|
||||
Add Interface
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -861,6 +913,11 @@
|
|||
interfaces: {},
|
||||
interfaceStats: {},
|
||||
|
||||
newInterfaceName: null,
|
||||
newInterfaceType: "TCPClientInterface",
|
||||
newInterfaceTargetHost: null,
|
||||
newInterfaceTargetPort: null,
|
||||
|
||||
};
|
||||
},
|
||||
mounted: function() {
|
||||
|
|
@ -1998,6 +2055,42 @@
|
|||
// reload interfaces
|
||||
await this.loadInterfaces();
|
||||
|
||||
},
|
||||
async addInterface() {
|
||||
|
||||
try {
|
||||
|
||||
// add interface
|
||||
const response = await window.axios.post(`/api/v1/reticulum/interfaces/add`, {
|
||||
name: this.newInterfaceName,
|
||||
type: this.newInterfaceType,
|
||||
target_host: this.newInterfaceTargetHost,
|
||||
target_port: this.newInterfaceTargetPort,
|
||||
});
|
||||
|
||||
// clear add interface form
|
||||
this.newInterfaceName = null;
|
||||
this.newInterfaceType = "TCPClientInterface";
|
||||
this.newInterfaceTargetHost = null;
|
||||
this.newInterfaceTargetPort = null;
|
||||
|
||||
// go to interfaces tab
|
||||
this.tab = "interfaces";
|
||||
|
||||
// show success message
|
||||
if(response.data.message){
|
||||
alert(response.data.message);
|
||||
}
|
||||
|
||||
} catch(e) {
|
||||
const message = e.response?.data?.message ?? "failed to add interface";
|
||||
alert(message);
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
// reload interfaces
|
||||
await this.loadInterfaces();
|
||||
|
||||
},
|
||||
onChatItemClick: function(chatItem) {
|
||||
if(!chatItem.is_actions_expanded){
|
||||
|
|
|
|||
70
web.py
70
web.py
|
|
@ -186,7 +186,7 @@ class ReticulumWebChat:
|
|||
self.reticulum.config.write()
|
||||
|
||||
return web.json_response({
|
||||
"message": "Interface Enabled",
|
||||
"message": "Interface is now enabled",
|
||||
})
|
||||
|
||||
# disable reticulum interface
|
||||
|
|
@ -209,7 +209,7 @@ class ReticulumWebChat:
|
|||
self.reticulum.config.write()
|
||||
|
||||
return web.json_response({
|
||||
"message": "Interface Disabled",
|
||||
"message": "Interface is now disabled",
|
||||
})
|
||||
|
||||
# delete reticulum interface
|
||||
|
|
@ -228,7 +228,71 @@ class ReticulumWebChat:
|
|||
self.reticulum.config.write()
|
||||
|
||||
return web.json_response({
|
||||
"message": "Interface Deleted",
|
||||
"message": "Interface has been deleted",
|
||||
})
|
||||
|
||||
# add reticulum interface
|
||||
@routes.post("/api/v1/reticulum/interfaces/add")
|
||||
async def index(request):
|
||||
|
||||
# get request data
|
||||
data = await request.json()
|
||||
interface_name = data.get('name')
|
||||
interface_type = data.get('type')
|
||||
|
||||
# ensure name is provided
|
||||
if interface_name is None or interface_name == "":
|
||||
return web.json_response({
|
||||
"message": "Name is required",
|
||||
}, status=422)
|
||||
|
||||
# ensure type name provided
|
||||
if interface_type is None or interface_type == "":
|
||||
return web.json_response({
|
||||
"message": "Type is required",
|
||||
}, status=422)
|
||||
|
||||
# get existing interfaces
|
||||
interfaces = {}
|
||||
if "interfaces" in self.reticulum.config:
|
||||
interfaces = self.reticulum.config["interfaces"]
|
||||
|
||||
# create interface details
|
||||
interface_details = {
|
||||
"type": interface_type,
|
||||
"interface_enabled": str(data.get('enabled', False)),
|
||||
}
|
||||
|
||||
# handle tcp client interface
|
||||
if interface_type == "TCPClientInterface":
|
||||
|
||||
interface_target_host = data.get('target_host')
|
||||
interface_target_port = data.get('target_port')
|
||||
|
||||
# ensure target host provided
|
||||
if interface_target_host is None or interface_target_host == "":
|
||||
return web.json_response({
|
||||
"message": "Target Host is required",
|
||||
}, status=422)
|
||||
|
||||
# ensure target port provided
|
||||
if interface_target_port is None or interface_target_port == "":
|
||||
return web.json_response({
|
||||
"message": "Target Port is required",
|
||||
}, status=422)
|
||||
|
||||
interface_details["target_host"] = data.get('target_host')
|
||||
interface_details["target_port"] = data.get('target_port')
|
||||
|
||||
# merge new interface into existing interfaces
|
||||
interfaces[interface_name] = interface_details
|
||||
self.reticulum.config["interfaces"] = interfaces
|
||||
|
||||
# save config
|
||||
self.reticulum.config.write()
|
||||
|
||||
return web.json_response({
|
||||
"message": "Interface has been added",
|
||||
})
|
||||
|
||||
# handle websocket clients
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue