feat(agent): self-heal rustdesk remote access
This commit is contained in:
parent
308f7b5712
commit
115d4a62e8
5 changed files with 391 additions and 71 deletions
|
|
@ -183,7 +183,16 @@ function hashToken(token: string) {
|
|||
return toHex(sha256(token))
|
||||
}
|
||||
|
||||
const REMOTE_ACCESS_TOKEN_GRACE_MS = 5 * 60 * 1000
|
||||
function getRemoteAccessTokenGraceMs() {
|
||||
const fallback = 15 * 60 * 1000
|
||||
const raw = process.env["REMOTE_ACCESS_TOKEN_GRACE_MS"]
|
||||
if (!raw) return fallback
|
||||
const parsed = Number(raw)
|
||||
if (!Number.isFinite(parsed) || parsed <= 0) return fallback
|
||||
return parsed
|
||||
}
|
||||
|
||||
const REMOTE_ACCESS_TOKEN_GRACE_MS = getRemoteAccessTokenGraceMs()
|
||||
|
||||
async function getTokenRecord(
|
||||
ctx: MutationCtx | QueryCtx,
|
||||
|
|
@ -777,6 +786,10 @@ export const heartbeat = mutation({
|
|||
if (args.metadata && typeof args.metadata === "object") {
|
||||
Object.assign(metadataPatch, args.metadata as Record<string, unknown>)
|
||||
}
|
||||
const remoteAccessSnapshot = metadataPatch["remoteAccessSnapshot"]
|
||||
if (remoteAccessSnapshot !== undefined) {
|
||||
delete metadataPatch["remoteAccessSnapshot"]
|
||||
}
|
||||
if (args.inventory && typeof args.inventory === "object") {
|
||||
metadataPatch.inventory = mergeInventory(metadataPatch.inventory, args.inventory as Record<string, unknown>)
|
||||
}
|
||||
|
|
@ -800,6 +813,10 @@ export const heartbeat = mutation({
|
|||
metadata: mergedMetadata,
|
||||
})
|
||||
|
||||
if (remoteAccessSnapshot) {
|
||||
await upsertRemoteAccessSnapshotFromHeartbeat(ctx, machine, remoteAccessSnapshot, now)
|
||||
}
|
||||
|
||||
await ctx.db.patch(token._id, {
|
||||
lastUsedAt: now,
|
||||
usageCount: (token.usageCount ?? 0) + 1,
|
||||
|
|
@ -2149,6 +2166,55 @@ function normalizeRemoteAccessList(raw: unknown): RemoteAccessEntry[] {
|
|||
return entries
|
||||
}
|
||||
|
||||
async function upsertRemoteAccessSnapshotFromHeartbeat(
|
||||
ctx: MutationCtx,
|
||||
machine: Doc<"machines">,
|
||||
snapshot: unknown,
|
||||
timestamp: number
|
||||
) {
|
||||
const normalized = normalizeRemoteAccessEntry(snapshot)
|
||||
if (!normalized) return
|
||||
const provider = (normalized.provider ?? "Remote").trim()
|
||||
const identifier = (normalized.identifier ?? "").trim()
|
||||
if (!identifier) return
|
||||
|
||||
const existingEntries = normalizeRemoteAccessList(machine.remoteAccess)
|
||||
const idx = existingEntries.findIndex(
|
||||
(entry) => entry.provider.toLowerCase() === provider.toLowerCase() && entry.identifier.toLowerCase() === identifier.toLowerCase()
|
||||
)
|
||||
|
||||
const entryId = idx >= 0 ? existingEntries[idx].id : createRemoteAccessId()
|
||||
const metadata = {
|
||||
...(normalized.metadata ?? {}),
|
||||
snapshotSource: "heartbeat",
|
||||
provider,
|
||||
identifier,
|
||||
lastVerifiedAt: timestamp,
|
||||
}
|
||||
|
||||
const updatedEntry: RemoteAccessEntry = {
|
||||
id: entryId,
|
||||
provider,
|
||||
identifier,
|
||||
url: normalized.url ?? null,
|
||||
username: normalized.username ?? null,
|
||||
password: normalized.password ?? null,
|
||||
notes: normalized.notes ?? null,
|
||||
lastVerifiedAt: timestamp,
|
||||
metadata,
|
||||
}
|
||||
|
||||
const nextEntries =
|
||||
idx >= 0
|
||||
? existingEntries.map((entry, index) => (index === idx ? updatedEntry : entry))
|
||||
: [...existingEntries, updatedEntry]
|
||||
|
||||
await ctx.db.patch(machine._id, {
|
||||
remoteAccess: nextEntries,
|
||||
updatedAt: timestamp,
|
||||
})
|
||||
}
|
||||
|
||||
export const updateRemoteAccess = mutation({
|
||||
args: {
|
||||
machineId: v.id("machines"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue