/* ===== RadiusUsers.js (Vue 3 + TT-Core) ===== */
const RadiusUsers = {
name: 'RadiusUsers',
template: `
`,
data: () => ({
window: window,
// Filters
billAddrDisplay: '',
billAddrCustnum: '',
username: '',
ip: '',
info: '',
searchMode: 'autocomplete',
// List Data
radiusUsers: [],
checkOnlineState: false,
isLoading: false,
searchCount: 0,
hasSearched: false,
visibleCount: 50,
observer: null,
// Modal State
selectedUsername: '',
selectedUserItem: null,
showRadacctModal: false,
showTransferModal: false,
showRouterManager: false,
// Extension Config
showExtensionIdModal: false,
extensionId: 'jglijfiddilckddlmbnlojmmlahboffh'
}),
computed: {
hasFilters() {
return this.billAddrDisplay || this.username || this.ip || this.info;
},
visibleUsers() {
return this.radiusUsers.slice(0, this.visibleCount);
}
},
mounted() {
const urlParams = new URLSearchParams(window.location.search);
const infoParam = urlParams.get('info');
if (infoParam) {
this.info = infoParam;
this.loadRadiusUsers();
}
this.observer = new IntersectionObserver(([e]) => {
if (e && e.isIntersecting) this.loadMore();
}, {root: this.$refs.tableWrap, threshold: 0.1});
if (this.$refs.sentinel) this.observer.observe(this.$refs.sentinel);
const savedExtensionId = localStorage.getItem('radiusExtensionId');
if (savedExtensionId) {
this.extensionId = savedExtensionId;
}
window.addEventListener('keydown', this.handleKeydown);
},
beforeUnmount() {
if (this.observer) this.observer.disconnect();
window.removeEventListener('keydown', this.handleKeydown);
},
updated() {
if (this.observer && this.$refs.sentinel) {
this.observer.disconnect();
this.observer.observe(this.$refs.sentinel);
}
},
methods: {
handleKeydown(e) {
if (e.code === 'KeyE' && e.ctrlKey && e.altKey) {
e.preventDefault();
this.showExtensionIdModal = true;
}
},
saveExtensionId() {
localStorage.setItem('radiusExtensionId', this.extensionId);
this.showExtensionIdModal = false;
window.notify('success', 'Extension ID gespeichert.');
},
onAddrSelect({custnum, display}) {
this.billAddrCustnum = custnum || '';
this.billAddrDisplay = display || '';
},
onModeChange(newMode) {
this.searchMode = newMode;
},
async loadRadiusUsers() {
this.isLoading = true;
this.radiusUsers = [];
this.hasSearched = true;
this.visibleCount = 50;
try {
const params = {
username: this.username || '',
info: this.info || '',
ip: this.ip || ''
};
if (this.searchMode === 'text') params.estmk_nr = this.billAddrDisplay || '';
else params.custnum = this.billAddrCustnum || '';
const { data } = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Radius/proxyUnsecureHTTPRequestToRadius`, { params });
if (Array.isArray(data) && data.length < 6) this.checkOnlineState = true;
this.radiusUsers = Array.isArray(data) ? data : [];
} catch (e) {
console.error(e);
}
this.isLoading = false;
const urlParams = new URLSearchParams(window.location.search);
const connectParam = urlParams.get('connect');
if (connectParam && connectParam.toLowerCase() === 'true' && this.radiusUsers.length === 1) {
try {
const { data: radacct } = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Radius/proxyUnsecureHTTPRequestToRadius`, {
params: { action2: 'fetchRadacct', username: this.radiusUsers[0].username }
});
if (radacct?.ip) {
this.onScanIp({ip: radacct.ip}, this.radiusUsers[0]);
}
} catch (error) {
console.error('Error fetching radacct:', error);
}
}
this.searchCount++;
},
clearFilters() {
this.billAddrDisplay = '';
this.billAddrCustnum = '';
this.username = '';
this.ip = '';
this.info = '';
this.radiusUsers = [];
this.hasSearched = false;
this.searchCount++;
this.visibleCount = 50;
},
loadMore() {
if (this.visibleCount < this.radiusUsers.length) this.visibleCount += 50;
},
// Modal Openers
openRadacctModal(username) {
this.selectedUsername = username;
this.showRadacctModal = true;
},
openTransferModal(username) {
this.selectedUsername = username;
this.showTransferModal = true;
},
openRouterManager(item) {
this.selectedUserItem = item;
this.showRouterManager = true;
},
// IP Scan Logic (Must remain in parent or be extracted to service, kept here for table interaction)
async onScanIp(payload, item) {
const {ip} = payload;
const info = item.info;
if (!ip) return;
window.notify('info', `Starte Scan für ${ip}...`);
try {
const { data } = await axios.get(`http://localhost:8094/scan`, {
params: { ip }
});
if (data.status === 'success' && data.url) {
const extensionId = this.extensionId;
const message = {
type: "INITIATE_ROUTER_LOGIN",
payload: {
ip: ip,
url: data.url,
info: info
}
};
if (window.chrome && chrome.runtime && chrome.runtime.sendMessage) {
try {
chrome.runtime.sendMessage(extensionId, message, (response) => {
if (chrome.runtime.lastError) {
console.warn("Senden an Erweiterung fehlgeschlagen:", chrome.runtime.lastError.message);
window.notify('warning', 'Scan-Daten konnten nicht an die Erweiterung gesendet werden. (Drücke STRG + ALT + E zum Konfigurieren)');
} else {
console.log("Erweiterung hat geantwortet:", response);
}
});
} catch (e) {
console.error("Fehler beim Senden an die Erweiterung:", e);
window.notify('error', 'Fehler beim Senden an die Erweiterung.');
}
} else {
console.warn("Chrome Extension Messaging API nicht verfügbar.");
window.notify('warning', 'Chrome Messaging API nicht gefunden.');
}
} else if (data.status === 'not_found') {
window.notify('warning', `Kein Gerät für ${ip} gefunden.`);
} else {
window.notify('error', 'Ungültige Antwort vom Scan-Server.');
}
} catch (error) {
console.error('IP-Scan fehlgeschlagen:', error);
window.notify('error', `Scan für ${ip} fehlgeschlagen.`);
}
}
}
};
if (window.VueApp) {
window.VueApp.component('radius-users', RadiusUsers);
}