pull/1094/merge
zombu4 2026-02-12 16:41:23 +08:00 committed by GitHub
commit 3fdd623005
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 107 additions and 15 deletions

View File

@ -690,15 +690,16 @@ def API_updatePeerSettings(configName):
preshared_key = data['preshared_key']
mtu = data['mtu']
keepalive = data['keepalive']
notes = data.get('notes', "")
wireguardConfig = WireguardConfigurations[configName]
foundPeer, peer = wireguardConfig.searchPeer(id)
if foundPeer:
if wireguardConfig.Protocol == 'wg':
status, msg = peer.updatePeer(name, private_key, preshared_key, dns_addresses,
allowed_ip, endpoint_allowed_ip, mtu, keepalive)
allowed_ip, endpoint_allowed_ip, mtu, keepalive, notes)
else:
status, msg = peer.updatePeer(name, private_key, preshared_key, dns_addresses,
allowed_ip, endpoint_allowed_ip, mtu, keepalive, "off")
allowed_ip, endpoint_allowed_ip, mtu, keepalive, "off", notes)
wireguardConfig.getPeers()
DashboardWebHooks.RunWebHook('peer_updated', {
"configuration": wireguardConfig.Name,
@ -849,6 +850,7 @@ def API_addPeers(configName):
mtu: int = data.get('mtu', None)
keep_alive: int = data.get('keepalive', None)
preshared_key: str = data.get('preshared_key', "")
notes: str = data.get('notes', "")
if type(mtu) is not int or mtu < 0 or mtu > 1460:
default: str = DashboardConfig.GetConfig("Peers", "peer_mtu")[1]
@ -900,6 +902,7 @@ def API_addPeers(configName):
"allowed_ip": ip,
"name": f"BulkPeer_{(addedCount + 1)}_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
"DNS": dns_addresses,
"notes": "",
"endpoint_allowed_ip": endpoint_allowed_ip,
"mtu": mtu,
"keepalive": keep_alive,
@ -963,6 +966,7 @@ def API_addPeers(configName):
"preshared_key": preshared_key,
"endpoint_allowed_ip": endpoint_allowed_ip,
"DNS": dns_addresses,
"notes": notes,
"mtu": mtu,
"keepalive": keep_alive,
"advanced_security": "off"
@ -1703,4 +1707,4 @@ def index():
if __name__ == "__main__":
startThreads()
DashboardPlugins.startThreads()
app.run(host=app_ip, debug=False, port=app_port)
app.run(host=app_ip, debug=False, port=app_port)

View File

@ -17,7 +17,7 @@ class AmneziaWGPeer(Peer):
def updatePeer(self, name: str, private_key: str,
preshared_key: str,
dns_addresses: str, allowed_ip: str, endpoint_allowed_ip: str, mtu: int,
keepalive: int, advanced_security: str) -> tuple[bool, str] or tuple[bool, None]:
keepalive: int, advanced_security: str, notes: str = "") -> tuple[bool, str] or tuple[bool, None]:
if not self.configuration.getStatus():
self.configuration.toggleConfiguration()
@ -81,7 +81,8 @@ class AmneziaWGPeer(Peer):
"mtu": mtu,
"keepalive": keepalive,
"preshared_key": preshared_key,
"advanced_security": advanced_security
"advanced_security": advanced_security,
"notes": notes
}).where(
self.configuration.peersTable.c.id == self.id
)
@ -89,4 +90,4 @@ class AmneziaWGPeer(Peer):
self.configuration.getPeers()
return True, None
except subprocess.CalledProcessError as exc:
return False, exc.output.decode("UTF-8").strip()
return False, exc.output.decode("UTF-8").strip()

View File

@ -77,6 +77,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
sqlalchemy.Column('advanced_security', sqlalchemy.String(255)),
sqlalchemy.Column('endpoint_allowed_ip', sqlalchemy.Text),
sqlalchemy.Column('name', sqlalchemy.Text),
sqlalchemy.Column('notes', sqlalchemy.Text),
sqlalchemy.Column('total_receive', sqlalchemy.Float),
sqlalchemy.Column('total_sent', sqlalchemy.Float),
sqlalchemy.Column('total_data', sqlalchemy.Float),
@ -101,6 +102,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
sqlalchemy.Column('advanced_security', sqlalchemy.String(255)),
sqlalchemy.Column('endpoint_allowed_ip', sqlalchemy.Text),
sqlalchemy.Column('name', sqlalchemy.Text),
sqlalchemy.Column('notes', sqlalchemy.Text),
sqlalchemy.Column('total_receive', sqlalchemy.Float),
sqlalchemy.Column('total_sent', sqlalchemy.Float),
sqlalchemy.Column('total_data', sqlalchemy.Float),
@ -138,6 +140,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
sqlalchemy.Column('advanced_security', sqlalchemy.String(255)),
sqlalchemy.Column('endpoint_allowed_ip', sqlalchemy.Text),
sqlalchemy.Column('name', sqlalchemy.Text),
sqlalchemy.Column('notes', sqlalchemy.Text),
sqlalchemy.Column('total_receive', sqlalchemy.Float),
sqlalchemy.Column('total_sent', sqlalchemy.Float),
sqlalchemy.Column('total_data', sqlalchemy.Float),
@ -171,6 +174,24 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
)
self.metadata.create_all(self.engine)
self.__ensurePeerNotesColumn()
def __ensurePeerNotesColumn(self):
inspector = sqlalchemy.inspect(self.engine)
existing_tables = set(inspector.get_table_names())
targets = [self.peersTable, self.peersRestrictedTable, self.peersDeletedTable]
with self.engine.begin() as conn:
for table in targets:
if table.name not in existing_tables:
continue
cols = [c["name"] for c in inspector.get_columns(table.name)]
if "notes" in cols:
continue
ddl = sqlalchemy.schema.DDL(
"ALTER TABLE %(table)s ADD COLUMN notes TEXT",
context={"table": table}
)
conn.execute(ddl)
def getPeers(self):
self.Peers.clear()
@ -217,6 +238,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
"endpoint_allowed_ip": self.DashboardConfig.GetConfig("Peers", "peer_endpoint_allowed_ip")[
1],
"name": i.get("name"),
"notes": "",
"total_receive": 0,
"total_sent": 0,
"total_data": 0,
@ -266,6 +288,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
"DNS": i['DNS'],
"endpoint_allowed_ip": i['endpoint_allowed_ip'],
"name": i['name'],
"notes": i.get("notes", ""),
"total_receive": 0,
"total_sent": 0,
"total_data": 0,
@ -319,4 +342,4 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
with self.engine.connect() as conn:
restricted = conn.execute(self.peersRestrictedTable.select()).mappings().fetchall()
for i in restricted:
self.RestrictedPeers.append(AmneziaWGPeer(i, self))
self.RestrictedPeers.append(AmneziaWGPeer(i, self))

View File

@ -22,6 +22,7 @@ class Peer:
self.DNS = tableData["DNS"]
self.endpoint_allowed_ip = tableData["endpoint_allowed_ip"]
self.name = tableData["name"]
self.notes = tableData.get("notes", "")
self.total_receive = tableData["total_receive"]
self.total_sent = tableData["total_sent"]
self.total_data = tableData["total_data"]
@ -52,7 +53,7 @@ class Peer:
def updatePeer(self, name: str, private_key: str,
preshared_key: str,
dns_addresses: str, allowed_ip: str, endpoint_allowed_ip: str, mtu: int,
keepalive: int) -> tuple[bool, str] or tuple[bool, None]:
keepalive: int, notes: str = "") -> tuple[bool, str] or tuple[bool, None]:
if not self.configuration.getStatus():
self.configuration.toggleConfiguration()
@ -114,7 +115,8 @@ class Peer:
"endpoint_allowed_ip": endpoint_allowed_ip,
"mtu": mtu,
"keepalive": keepalive,
"preshared_key": preshared_key
"preshared_key": preshared_key,
"notes": notes
}).where(
self.configuration.peersTable.c.id == self.id
)
@ -351,4 +353,4 @@ class Peer:
hours, remainder = divmod(delta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}"
return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}"

View File

@ -241,6 +241,7 @@ class WireguardConfiguration:
sqlalchemy.Column('DNS', sqlalchemy.Text),
sqlalchemy.Column('endpoint_allowed_ip', sqlalchemy.Text),
sqlalchemy.Column('name', sqlalchemy.Text),
sqlalchemy.Column('notes', sqlalchemy.Text),
sqlalchemy.Column('total_receive', sqlalchemy.Float),
sqlalchemy.Column('total_sent', sqlalchemy.Float),
sqlalchemy.Column('total_data', sqlalchemy.Float),
@ -264,6 +265,7 @@ class WireguardConfiguration:
sqlalchemy.Column('DNS', sqlalchemy.Text),
sqlalchemy.Column('endpoint_allowed_ip', sqlalchemy.Text),
sqlalchemy.Column('name', sqlalchemy.Text),
sqlalchemy.Column('notes', sqlalchemy.Text),
sqlalchemy.Column('total_receive', sqlalchemy.Float),
sqlalchemy.Column('total_sent', sqlalchemy.Float),
sqlalchemy.Column('total_data', sqlalchemy.Float),
@ -310,6 +312,7 @@ class WireguardConfiguration:
sqlalchemy.Column('DNS', sqlalchemy.Text),
sqlalchemy.Column('endpoint_allowed_ip', sqlalchemy.Text),
sqlalchemy.Column('name', sqlalchemy.Text),
sqlalchemy.Column('notes', sqlalchemy.Text),
sqlalchemy.Column('total_receive', sqlalchemy.Float),
sqlalchemy.Column('total_sent', sqlalchemy.Float),
sqlalchemy.Column('total_data', sqlalchemy.Float),
@ -334,6 +337,24 @@ class WireguardConfiguration:
)
self.metadata.create_all(self.engine)
self.__ensurePeerNotesColumn()
def __ensurePeerNotesColumn(self):
inspector = sqlalchemy.inspect(self.engine)
existing_tables = set(inspector.get_table_names())
targets = [self.peersTable, self.peersRestrictedTable, self.peersDeletedTable]
with self.engine.begin() as conn:
for table in targets:
if table.name not in existing_tables:
continue
cols = [c["name"] for c in inspector.get_columns(table.name)]
if "notes" in cols:
continue
ddl = sqlalchemy.schema.DDL(
"ALTER TABLE %(table)s ADD COLUMN notes TEXT",
context={"table": table}
)
conn.execute(ddl)
def __dumpDatabase(self):
with self.engine.connect() as conn:
@ -442,6 +463,7 @@ class WireguardConfiguration:
"endpoint_allowed_ip": self.DashboardConfig.GetConfig("Peers", "peer_endpoint_allowed_ip")[
1],
"name": i.get("name"),
"notes": "",
"total_receive": 0,
"total_sent": 0,
"total_data": 0,
@ -534,6 +556,7 @@ class WireguardConfiguration:
"DNS": i['DNS'],
"endpoint_allowed_ip": i['endpoint_allowed_ip'],
"name": i['name'],
"notes": i.get("notes", ""),
"total_receive": 0,
"total_sent": 0,
"total_data": 0,
@ -1291,4 +1314,4 @@ class WireguardConfiguration:
conn.execute(sqlalchemy.text('VACUUM;'))
except Exception as e:
return False
return True
return True

View File

@ -22,6 +22,7 @@ const peerData = ref({
bulkAdd: false,
bulkAddAmount: 0,
name: "",
notes: "",
allowed_ips: [],
private_key: "",
public_key: "",
@ -124,6 +125,18 @@ watch(() => {
<div class="d-flex flex-column gap-2">
<DnsInput :saving="saving" :data="peerData"></DnsInput>
<EndpointAllowedIps :saving="saving" :data="peerData"></EndpointAllowedIps>
<div v-if="!peerData.bulkAdd">
<label for="peer_notes_add_textbox" class="form-label">
<small class="text-muted">
<LocaleText t="Notes"></LocaleText>
</small>
</label>
<textarea class="form-control form-control-sm rounded-3"
:disabled="saving"
v-model="peerData.notes"
id="peer_notes_add_textbox"
rows="3"></textarea>
</div>
<div class="row gy-3">
<div class="col-sm" v-if="!peerData.bulkAdd">
<PresharedKeyInput :saving="saving" :data="peerData" :bulk="peerData.bulkAdd"></PresharedKeyInput>
@ -175,4 +188,4 @@ watch(() => {
<style scoped>
</style>
</style>

View File

@ -92,6 +92,16 @@ defineEmits(['close'])
</div>
</div>
</div>
<div class="col-12" v-if="selectedPeer.notes && selectedPeer.notes.length > 0">
<div class="card rounded-3 bg-transparent h-100">
<div class="card-body py-2">
<p class="mb-1 text-muted"><small>
<LocaleText t="Notes"></LocaleText>
</small></p>
<p class="mb-0" style="white-space: pre-wrap">{{selectedPeer.notes}}</p>
</div>
</div>
</div>
<div class="col-12 col-lg-3">
<div class="card rounded-3 bg-transparent h-100">
@ -178,4 +188,4 @@ defineEmits(['close'])
<style scoped>
</style>
</style>

View File

@ -25,6 +25,9 @@ export default {
reset(){
if (this.selectedPeer){
this.data = JSON.parse(JSON.stringify(this.selectedPeer))
if (this.data.notes === undefined || this.data.notes === null){
this.data.notes = ""
}
this.dataChanged = false;
}
},
@ -60,7 +63,7 @@ export default {
this.reset();
},
mounted() {
this.$el.querySelectorAll("input").forEach(x => {
this.$el.querySelectorAll("input, textarea").forEach(x => {
x.addEventListener("change", () => {
this.dataChanged = true;
});
@ -99,6 +102,19 @@ export default {
v-model="this.data.name"
id="peer_name_textbox" placeholder="">
</div>
<div>
<label for="peer_notes_textbox" class="form-label">
<small class="text-muted">
<LocaleText t="Notes"></LocaleText>
</small>
</label>
<textarea class="form-control form-control-sm rounded-3"
:disabled="this.saving"
v-model="this.data.notes"
id="peer_notes_textbox"
rows="3"
placeholder=""></textarea>
</div>
<div>
<div class="d-flex position-relative">
<label for="peer_private_key_textbox" class="form-label">
@ -260,4 +276,4 @@ export default {
top: 35px;
right: 12px;
}
</style>
</style>