import { computed, type Ref } from "vue"; import type { MagicDeviceInfo, IphoneDeviceState } from "./useTauri"; export type DeviceStatus = "active" | "cooldown" | "revoked" | "pending" | "unprotected"; export interface ComputedDevice { deviceId: string; name: string; platform: "mac" | "windows" | "ios" | "android" | "unknown"; model: string | null; osVersion: string | null; status: DeviceStatus; isCurrent: boolean; cooldownUntil: string | null; lastSeenAt: string | null; enrolledAt: string | null; } const ENROLLMENT_PROFILE_ID = "org.rebreak.mdm.enrollment"; const LOCK_PROFILE_ID = "org.rebreak.protection.contentfilter.sideload"; const APP_BUNDLE_ID = "org.rebreak.app"; function normalizePlatform(value: string | null | undefined): ComputedDevice["platform"] { const n = (value ?? "").toLowerCase(); if (n.startsWith("mac") || n === "darwin") return "mac"; if (n.startsWith("ios") || n.startsWith("iphone") || n.startsWith("ipad")) return "ios"; if (n.startsWith("android")) return "android"; if (n.startsWith("win")) return "windows"; return "unknown"; } function normalizeHostname(value: string): string { return (value.toLowerCase().split(".")[0] ?? "").replace(/[^a-z0-9]/g, ""); } function mapToComputedDevice(d: MagicDeviceInfo, isCurrent: boolean): ComputedDevice { return { deviceId: d.deviceId, name: d.model ?? d.hostname, platform: normalizePlatform(d.model ?? d.hostname), model: d.model, osVersion: d.osVersion, status: d.status as DeviceStatus, isCurrent, cooldownUntil: d.cooldownUntil, lastSeenAt: d.lastSeenAt, enrolledAt: d.magicEnrolledAt, }; } export function useDeviceStatus( devices: Ref, localHostname: Ref, iphone: Ref, currentDeviceId?: Ref, ) { function isCurrentDevice(d: MagicDeviceInfo): boolean { if (currentDeviceId?.value) { return d.deviceId === currentDeviceId.value; } if (!localHostname.value) return false; const local = normalizeHostname(localHostname.value); return normalizeHostname(d.hostname) === local; } const currentBackendDevice = computed(() => { const found = devices.value.find(isCurrentDevice); if (!found) return null; return mapToComputedDevice(found, true); }); const otherDevices = computed(() => { const currentId = currentBackendDevice.value?.deviceId; return devices.value .filter((d) => d.deviceId !== currentId) .map((d) => mapToComputedDevice(d, false)); }); const iosDevices = computed(() => otherDevices.value.filter((d) => d.platform === "ios"), ); const desktopDevices = computed(() => otherDevices.value.filter((d) => d.platform === "mac" || d.platform === "windows"), ); const iosStars = computed(() => { if (!iphone.value) return null; return { enrollment: iphone.value.installedProfileIDs?.includes(ENROLLMENT_PROFILE_ID) ?? false, sideload: iphone.value.installedProfileIDs?.includes(LOCK_PROFILE_ID) ?? false, app: iphone.value.installedAppBundleIDs?.includes(APP_BUNDLE_ID) ?? false, isSupervised: iphone.value.isSupervised, }; }); return { currentBackendDevice, otherDevices, iosDevices, desktopDevices, iosStars, }; }