mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-03-28 17:42:45 +01:00
fix(paths): prevent duplicate repeater IDs in path
Blocks adding the same hop prefix twice via all three methods: - List picker: shows warning notification, ignores click - Map picker: shows warning notification, keeps selection - Manual entry: validates on Add Path, rejects with error Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1849,6 +1849,18 @@ function setupPathFormHandlers(pubkey) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for duplicate hops in manually entered path
|
||||||
|
const chunk = hashSize * 2;
|
||||||
|
const hops = [];
|
||||||
|
for (let i = 0; i < pathHex.length; i += chunk) {
|
||||||
|
hops.push(pathHex.substring(i, i + chunk).toLowerCase());
|
||||||
|
}
|
||||||
|
const dupes = hops.filter((h, i) => hops.indexOf(h) !== i);
|
||||||
|
if (dupes.length > 0) {
|
||||||
|
showNotification(`Duplicate hop(s): ${[...new Set(dupes)].map(d => d.toUpperCase()).join(', ')}`, 'danger');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/contacts/${encodeURIComponent(pubkey)}/paths`, {
|
const response = await fetch(`/api/contacts/${encodeURIComponent(pubkey)}/paths`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -1993,6 +2005,12 @@ function renderRepeaterList(listEl, repeaters, pubkey) {
|
|||||||
${samePrefix > 1 ? '<i class="bi bi-exclamation-triangle text-warning" title="' + samePrefix + ' repeaters share this prefix"></i>' : ''}
|
${samePrefix > 1 ? '<i class="bi bi-exclamation-triangle text-warning" title="' + samePrefix + ' repeaters share this prefix"></i>' : ''}
|
||||||
`;
|
`;
|
||||||
item.addEventListener('click', () => {
|
item.addEventListener('click', () => {
|
||||||
|
// Check for duplicate hop
|
||||||
|
const existingHops = getCurrentPathHops(hashSize);
|
||||||
|
if (existingHops.includes(prefix.toLowerCase())) {
|
||||||
|
showNotification(`${prefix} is already in the path`, 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Append hop to path hex input
|
// Append hop to path hex input
|
||||||
const current = hexInput.value.replace(/[,\s→]/g, '').trim();
|
const current = hexInput.value.replace(/[,\s→]/g, '').trim();
|
||||||
const newVal = current + prefix.toLowerCase();
|
const newVal = current + prefix.toLowerCase();
|
||||||
@@ -2021,6 +2039,21 @@ function filterRepeaterList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of hop prefixes currently in the path hex input.
|
||||||
|
*/
|
||||||
|
function getCurrentPathHops(hashSize) {
|
||||||
|
const hexInput = document.getElementById('dmPathHexInput');
|
||||||
|
if (!hexInput) return [];
|
||||||
|
const rawHex = hexInput.value.replace(/[,\s→]/g, '').trim().toLowerCase();
|
||||||
|
const chunk = hashSize * 2;
|
||||||
|
const hops = [];
|
||||||
|
for (let i = 0; i < rawHex.length; i += chunk) {
|
||||||
|
hops.push(rawHex.substring(i, i + chunk));
|
||||||
|
}
|
||||||
|
return hops;
|
||||||
|
}
|
||||||
|
|
||||||
function checkUniquenessWarning(repeaters, hashSize) {
|
function checkUniquenessWarning(repeaters, hashSize) {
|
||||||
const warningEl = document.getElementById('dmPathUniquenessWarning');
|
const warningEl = document.getElementById('dmPathUniquenessWarning');
|
||||||
if (!warningEl) return;
|
if (!warningEl) return;
|
||||||
@@ -2101,6 +2134,12 @@ function openRepeaterMapPicker() {
|
|||||||
if (!_rptMapSelectedRepeater) return;
|
if (!_rptMapSelectedRepeater) return;
|
||||||
const hashSize = parseInt(document.querySelector('input[name="pathHashSize"]:checked').value);
|
const hashSize = parseInt(document.querySelector('input[name="pathHashSize"]:checked').value);
|
||||||
const prefix = _rptMapSelectedRepeater.public_key.substring(0, hashSize * 2).toLowerCase();
|
const prefix = _rptMapSelectedRepeater.public_key.substring(0, hashSize * 2).toLowerCase();
|
||||||
|
// Check for duplicate hop
|
||||||
|
const existingHops = getCurrentPathHops(hashSize);
|
||||||
|
if (existingHops.includes(prefix)) {
|
||||||
|
showNotification(`${prefix.toUpperCase()} is already in the path`, 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
const hexInput = document.getElementById('dmPathHexInput');
|
const hexInput = document.getElementById('dmPathHexInput');
|
||||||
if (hexInput) {
|
if (hexInput) {
|
||||||
const current = hexInput.value.replace(/[,\s→]/g, '').trim();
|
const current = hexInput.value.replace(/[,\s→]/g, '').trim();
|
||||||
|
|||||||
Reference in New Issue
Block a user