chore(home): mirror from kalinamall (9883e6a) with papatramp URLs
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
import { onUnmounted, ref } from "vue";
|
||||
import {
|
||||
fetchEventAction,
|
||||
postEventLogoff,
|
||||
postEventQwinsta,
|
||||
type AgentCommandResponse,
|
||||
type EventSummary,
|
||||
} from "../api";
|
||||
import { rdgQwinstaEventId } from "../utils/rdgFlap";
|
||||
|
||||
export type QwinstaSessionRow = {
|
||||
sessionName: string;
|
||||
userName: string;
|
||||
id: number;
|
||||
state: string;
|
||||
};
|
||||
|
||||
function parseQwinstaSessions(stdout: string, actorUser: string): QwinstaSessionRow[] {
|
||||
const lines = stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
||||
const rows: QwinstaSessionRow[] = [];
|
||||
for (const line of lines) {
|
||||
if (/^SESSION/i.test(line) || /^---/.test(line)) continue;
|
||||
const parts = line.split(/\s+/);
|
||||
if (parts.length < 4) continue;
|
||||
const sessionName = parts[0].replace(/^>/, "");
|
||||
const userName = parts[1];
|
||||
const id = Number.parseInt(parts[2], 10);
|
||||
const state = parts.slice(3).join(" ");
|
||||
if (!Number.isFinite(id)) continue;
|
||||
const norm = (s: string) => s.replace(/^B26\\/i, "").toLowerCase();
|
||||
const matchUser = actorUser && norm(userName).includes(norm(actorUser));
|
||||
if (actorUser && !matchUser) continue;
|
||||
rows.push({ sessionName, userName, id, state });
|
||||
}
|
||||
if (rows.length === 0 && stdout.trim()) {
|
||||
for (const line of lines) {
|
||||
if (/^SESSION/i.test(line) || /^---/.test(line)) continue;
|
||||
const parts = line.split(/\s+/);
|
||||
if (parts.length < 4) continue;
|
||||
const id = Number.parseInt(parts[2], 10);
|
||||
if (!Number.isFinite(id)) continue;
|
||||
rows.push({
|
||||
sessionName: parts[0].replace(/^>/, ""),
|
||||
userName: parts[1],
|
||||
id,
|
||||
state: parts.slice(3).join(" "),
|
||||
});
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
export function useRdgQwinsta() {
|
||||
let qwinstaPollTimer: ReturnType<typeof setInterval> | null = null;
|
||||
const qwinstaLoadingId = ref<number | null>(null);
|
||||
const qwinstaModal = ref({
|
||||
open: false,
|
||||
eventId: 0,
|
||||
actorUser: "",
|
||||
commandUuid: "",
|
||||
target: "",
|
||||
clientHostname: "",
|
||||
internalIp: "",
|
||||
loading: false,
|
||||
error: "",
|
||||
stdout: "",
|
||||
sessions: [] as QwinstaSessionRow[],
|
||||
logoffId: null as number | null,
|
||||
});
|
||||
|
||||
function stopQwinstaPoll() {
|
||||
if (qwinstaPollTimer) {
|
||||
clearInterval(qwinstaPollTimer);
|
||||
qwinstaPollTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function closeQwinstaModal() {
|
||||
stopQwinstaPoll();
|
||||
qwinstaModal.value.open = false;
|
||||
}
|
||||
|
||||
function applyCommandResult(eventId: number, actorUser: string, cmd: AgentCommandResponse) {
|
||||
if (cmd.status === "pending") return false;
|
||||
qwinstaModal.value.loading = false;
|
||||
if (cmd.status === "failed") {
|
||||
qwinstaModal.value.error = cmd.result_stderr || cmd.result_stdout || "Команда завершилась с ошибкой";
|
||||
return true;
|
||||
}
|
||||
qwinstaModal.value.stdout = cmd.result_stdout || "";
|
||||
qwinstaModal.value.sessions = parseQwinstaSessions(qwinstaModal.value.stdout, actorUser);
|
||||
return true;
|
||||
}
|
||||
|
||||
function applyCommandMeta(modal: typeof qwinstaModal.value, cmd: AgentCommandResponse) {
|
||||
modal.target = cmd.target || "";
|
||||
modal.clientHostname = cmd.client_hostname || "";
|
||||
modal.internalIp = cmd.internal_ip || "";
|
||||
}
|
||||
|
||||
function pollQwinstaCommand(eventId: number, commandUuid: string, actorUser: string) {
|
||||
stopQwinstaPoll();
|
||||
qwinstaPollTimer = setInterval(async () => {
|
||||
try {
|
||||
const cmd = await fetchEventAction(eventId, commandUuid);
|
||||
if (applyCommandResult(eventId, actorUser, cmd)) {
|
||||
stopQwinstaPoll();
|
||||
}
|
||||
} catch (e) {
|
||||
qwinstaModal.value.loading = false;
|
||||
qwinstaModal.value.error = e instanceof Error ? e.message : "Ошибка опроса команды";
|
||||
stopQwinstaPoll();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
async function runQwinsta(event: EventSummary) {
|
||||
const targetId = rdgQwinstaEventId(event) ?? event.id;
|
||||
qwinstaLoadingId.value = event.id;
|
||||
qwinstaModal.value = {
|
||||
open: true,
|
||||
eventId: targetId,
|
||||
actorUser: event.actor_user || "",
|
||||
commandUuid: "",
|
||||
target: "",
|
||||
clientHostname: "",
|
||||
internalIp: "",
|
||||
loading: true,
|
||||
error: "",
|
||||
stdout: "",
|
||||
sessions: [],
|
||||
logoffId: null,
|
||||
};
|
||||
try {
|
||||
const cmd = await postEventQwinsta(targetId);
|
||||
applyCommandMeta(qwinstaModal.value, cmd);
|
||||
qwinstaModal.value.commandUuid = cmd.command_uuid;
|
||||
if (applyCommandResult(targetId, event.actor_user || "", cmd)) {
|
||||
return;
|
||||
}
|
||||
pollQwinstaCommand(targetId, cmd.command_uuid, event.actor_user || "");
|
||||
} catch (e) {
|
||||
qwinstaModal.value.loading = false;
|
||||
qwinstaModal.value.error = e instanceof Error ? e.message : "Не удалось отправить qwinsta";
|
||||
} finally {
|
||||
qwinstaLoadingId.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function runLogoff(sessionId: number) {
|
||||
const modal = qwinstaModal.value;
|
||||
if (!modal.eventId) return;
|
||||
if (!window.confirm(`Завершить сеанс ID ${sessionId}?`)) return;
|
||||
modal.logoffId = sessionId;
|
||||
modal.error = "";
|
||||
try {
|
||||
const cmd = await postEventLogoff(modal.eventId, sessionId);
|
||||
applyCommandMeta(modal, cmd);
|
||||
if (cmd.status === "failed") {
|
||||
modal.error = cmd.result_stderr || cmd.result_stdout || "logoff failed";
|
||||
return;
|
||||
}
|
||||
modal.loading = true;
|
||||
modal.stdout = "";
|
||||
modal.sessions = [];
|
||||
const again = await postEventQwinsta(modal.eventId);
|
||||
applyCommandMeta(modal, again);
|
||||
if (applyCommandResult(modal.eventId, modal.actorUser, again)) {
|
||||
return;
|
||||
}
|
||||
pollQwinstaCommand(modal.eventId, again.command_uuid, modal.actorUser);
|
||||
} catch (e) {
|
||||
modal.error = e instanceof Error ? e.message : "logoff error";
|
||||
} finally {
|
||||
modal.logoffId = null;
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => stopQwinstaPoll());
|
||||
|
||||
return {
|
||||
qwinstaLoadingId,
|
||||
qwinstaModal,
|
||||
closeQwinstaModal,
|
||||
runQwinsta,
|
||||
runLogoff,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user