chore(agent): add remote access logging and state

This commit is contained in:
Esdras Renan 2025-11-11 18:26:37 -03:00
parent 07d304b5b1
commit cdf3feaa96

View file

@ -87,6 +87,7 @@ type RustdeskProvisioningResult = {
type RustdeskInfo = RustdeskProvisioningResult & { type RustdeskInfo = RustdeskProvisioningResult & {
lastProvisionedAt: number lastProvisionedAt: number
lastSyncedAt?: number | null lastSyncedAt?: number | null
lastError?: string | null
} }
const RUSTDESK_STORE_KEY = "rustdesk" const RUSTDESK_STORE_KEY = "rustdesk"
@ -196,6 +197,11 @@ async function writeRustdeskInfo(store: Store, info: RustdeskInfo): Promise<void
await store.save() await store.save()
} }
function logDesktop(message: string, data?: Record<string, unknown>) {
const enriched = data ? `${message} ${JSON.stringify(data)}` : message
console.log(`[raven] ${enriched}`)
}
function bytes(n?: number) { function bytes(n?: number) {
if (!n || !Number.isFinite(n)) return "—" if (!n || !Number.isFinite(n)) return "—"
const u = ["B","KB","MB","GB","TB"] const u = ["B","KB","MB","GB","TB"]
@ -492,6 +498,7 @@ function App() {
// Não assume online sem validar; valida abaixo em outro efeito // Não assume online sem validar; valida abaixo em outro efeito
} catch { } catch {
setError("Falha ao carregar estado do agente.") setError("Falha ao carregar estado do agente.")
logDesktop("store-load:error")
} }
})() })()
}, []) }, [])
@ -516,6 +523,7 @@ function App() {
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(heartbeatPayload), body: JSON.stringify(heartbeatPayload),
}) })
logDesktop("heartbeat:sent", { ok: res.ok, status: res.status })
if (cancelled) return if (cancelled) return
if (res.ok) { if (res.ok) {
tokenVerifiedRef.current = true tokenVerifiedRef.current = true
@ -551,6 +559,7 @@ function App() {
const healed = await attemptSelfHeal("heartbeat") const healed = await attemptSelfHeal("heartbeat")
if (cancelled) return if (cancelled) return
if (healed) { if (healed) {
logDesktop("heartbeat:selfheal:success")
setStatus("online") setStatus("online")
return return
} }
@ -577,6 +586,7 @@ function App() {
} catch (err) { } catch (err) {
if (!cancelled) { if (!cancelled) {
console.error("Falha ao validar token (rede)", err) console.error("Falha ao validar token (rede)", err)
logDesktop("heartbeat:error", { message: err instanceof Error ? err.message : String(err) })
tokenVerifiedRef.current = true tokenVerifiedRef.current = true
setTokenValidationTick((tick) => tick + 1) setTokenValidationTick((tick) => tick + 1)
} }
@ -637,7 +647,9 @@ useEffect(() => {
collaboratorName: normalizedName, collaboratorName: normalizedName,
} }
setConfig(nextConfig) setConfig(nextConfig)
writeConfig(store, nextConfig).catch((err) => console.error("Falha ao atualizar colaborador", err)) writeConfig(store, nextConfig)
.then(() => logDesktop("config:update:collaborator", { email: normalizedEmail }))
.catch((err) => console.error("Falha ao atualizar colaborador", err))
}, [store, config, config?.collaboratorEmail, config?.collaboratorName, collabEmail, collabName]) }, [store, config, config?.collaboratorEmail, config?.collaboratorName, collabEmail, collabName])
useEffect(() => { useEffect(() => {
@ -656,7 +668,9 @@ useEffect(() => {
if (nextAppUrl !== config.appUrl || nextApiUrl !== config.apiBaseUrl) { if (nextAppUrl !== config.appUrl || nextApiUrl !== config.apiBaseUrl) {
const updatedConfig = { ...config, appUrl: nextAppUrl, apiBaseUrl: nextApiUrl } const updatedConfig = { ...config, appUrl: nextAppUrl, apiBaseUrl: nextApiUrl }
setConfig(updatedConfig) setConfig(updatedConfig)
writeConfig(store, updatedConfig).catch((err) => console.error("Falha ao atualizar configuração", err)) writeConfig(store, updatedConfig)
.then(() => logDesktop("config:update:url"))
.catch((err) => console.error("Falha ao atualizar configuração", err))
} }
}, [store, config]) }, [store, config])
@ -734,6 +748,7 @@ const resolvedAppUrl = useMemo(() => {
body: JSON.stringify({ machineToken, ...payload }), body: JSON.stringify({ machineToken, ...payload }),
}) })
if (!response.ok) { if (!response.ok) {
logDesktop("remoteAccess:sync:error", { status: response.status })
const text = await response.text() const text = await response.text()
if (allowRetry && isTokenRevokedMessage(text)) { if (allowRetry && isTokenRevokedMessage(text)) {
const healed = await attemptSelfHeal("remote-access") const healed = await attemptSelfHeal("remote-access")
@ -744,7 +759,8 @@ const resolvedAppUrl = useMemo(() => {
} }
throw new Error(text.slice(0, 300) || "Falha ao registrar acesso remoto") throw new Error(text.slice(0, 300) || "Falha ao registrar acesso remoto")
} }
const nextInfo: RustdeskInfo = { ...info, lastSyncedAt: Date.now() } const nextInfo: RustdeskInfo = { ...info, lastSyncedAt: Date.now(), lastError: null }
logDesktop("remoteAccess:sync:success", { id: info.id })
await writeRustdeskInfo(store, nextInfo) await writeRustdeskInfo(store, nextInfo)
setRustdeskInfo(nextInfo) setRustdeskInfo(nextInfo)
} catch (error) { } catch (error) {
@ -757,6 +773,10 @@ const resolvedAppUrl = useMemo(() => {
} }
} }
console.error("Falha ao sincronizar acesso remoto com a plataforma", error) console.error("Falha ao sincronizar acesso remoto com a plataforma", error)
const failedInfo: RustdeskInfo = { ...info, lastError: message }
await writeRustdeskInfo(store, failedInfo)
setRustdeskInfo(failedInfo)
logDesktop("remoteAccess:sync:failed", { id: info.id, error: message })
} }
}, },
[store, attemptSelfHeal] [store, attemptSelfHeal]
@ -888,6 +908,7 @@ useEffect(() => {
}) })
await provisionRustdesk(data.machineId, data.machineToken) await provisionRustdesk(data.machineId, data.machineToken)
logDesktop("register:rustdesk:done", { machineId: data.machineId })
// Abre o sistema imediatamente após registrar (evita ficar com token inválido no fluxo antigo) // Abre o sistema imediatamente após registrar (evita ficar com token inválido no fluxo antigo)
try { try {