feat: RDG qwinsta/logoff via WinRM on client workstation (0.11.6)
SAC resolves internal_ip to a registered Windows host and runs qwinsta/logoff synchronously over WinRM instead of queueing commands to the gateway agent.
This commit is contained in:
@@ -305,7 +305,8 @@
|
||||
|
||||
<div v-if="qwinstaModal.open" class="modal-backdrop" @click.self="closeQwinstaModal">
|
||||
<div class="modal-card qwinsta-modal" role="dialog" aria-modal="true">
|
||||
<h3>qwinsta — событие #{{ qwinstaModal.eventId }}</h3>
|
||||
<h3>qwinsta — {{ qwinstaModal.clientHostname || qwinstaModal.target || `#${qwinstaModal.eventId}` }}</h3>
|
||||
<p v-if="qwinstaModal.internalIp" class="muted qwinsta-meta">Клиентский ПК: {{ qwinstaModal.internalIp }}</p>
|
||||
<p v-if="qwinstaModal.error" class="error">{{ qwinstaModal.error }}</p>
|
||||
<p v-else-if="qwinstaModal.loading">Ожидание ответа агента…</p>
|
||||
<template v-else>
|
||||
@@ -412,6 +413,9 @@ const qwinstaModal = ref({
|
||||
eventId: 0,
|
||||
actorUser: "",
|
||||
commandUuid: "",
|
||||
target: "",
|
||||
clientHostname: "",
|
||||
internalIp: "",
|
||||
loading: false,
|
||||
error: "",
|
||||
stdout: "",
|
||||
@@ -494,6 +498,12 @@ function pollQwinstaCommand(eventId: number, commandUuid: string, actorUser: str
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function applyCommandMeta(modal: typeof qwinstaModal.value, cmd: AgentCommandResponse) {
|
||||
modal.target = cmd.target || "";
|
||||
modal.clientHostname = cmd.client_hostname || "";
|
||||
modal.internalIp = cmd.internal_ip || "";
|
||||
}
|
||||
|
||||
async function runQwinsta(event: EventSummary) {
|
||||
qwinstaLoadingId.value = event.id;
|
||||
qwinstaModal.value = {
|
||||
@@ -501,6 +511,9 @@ async function runQwinsta(event: EventSummary) {
|
||||
eventId: event.id,
|
||||
actorUser: event.actor_user || "",
|
||||
commandUuid: "",
|
||||
target: "",
|
||||
clientHostname: "",
|
||||
internalIp: "",
|
||||
loading: true,
|
||||
error: "",
|
||||
stdout: "",
|
||||
@@ -509,6 +522,7 @@ async function runQwinsta(event: EventSummary) {
|
||||
};
|
||||
try {
|
||||
const cmd = await postEventQwinsta(event.id);
|
||||
applyCommandMeta(qwinstaModal.value, cmd);
|
||||
qwinstaModal.value.commandUuid = cmd.command_uuid;
|
||||
if (applyCommandResult(event.id, event.actor_user || "", cmd)) {
|
||||
return;
|
||||
@@ -530,25 +544,20 @@ async function runLogoff(sessionId: number) {
|
||||
modal.error = "";
|
||||
try {
|
||||
const cmd = await postEventLogoff(modal.eventId, sessionId);
|
||||
if (cmd.status === "pending") {
|
||||
const deadline = Date.now() + 60000;
|
||||
while (Date.now() < deadline) {
|
||||
await new Promise((r) => setTimeout(r, 2000));
|
||||
const polled = await fetchEventAction(modal.eventId, cmd.command_uuid);
|
||||
if (polled.status !== "pending") {
|
||||
if (polled.status === "failed") {
|
||||
modal.error = polled.result_stderr || "logoff failed";
|
||||
} else {
|
||||
modal.loading = true;
|
||||
modal.stdout = "";
|
||||
modal.sessions = [];
|
||||
const again = await postEventQwinsta(modal.eventId);
|
||||
pollQwinstaCommand(modal.eventId, again.command_uuid, modal.actorUser);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
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 {
|
||||
@@ -849,6 +858,11 @@ onUnmounted(() => {
|
||||
padding: 1rem 1.25rem;
|
||||
}
|
||||
|
||||
.qwinsta-meta {
|
||||
margin: 0 0 0.75rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.qwinsta-raw {
|
||||
font-size: 0.8rem;
|
||||
max-height: 12rem;
|
||||
|
||||
Reference in New Issue
Block a user