109 lines
3.4 KiB
TypeScript

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;
mdmId: 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.hostname ?? d.model ?? "Unbenanntes Gerät",
platform: normalizePlatform(d.model ?? d.hostname),
model: d.model,
osVersion: d.osVersion,
mdmId: d.mdmId ?? null,
status: d.status as DeviceStatus,
isCurrent,
cooldownUntil: d.cooldownUntil,
lastSeenAt: d.lastSeenAt,
enrolledAt: d.magicEnrolledAt,
};
}
export function useDeviceStatus(
devices: Ref<MagicDeviceInfo[]>,
localHostname: Ref<string | null>,
iphone: Ref<IphoneDeviceState | null>,
currentDeviceId?: Ref<string | null>,
currentHardwareId?: Ref<string | null>,
) {
function isCurrentDevice(d: MagicDeviceInfo): boolean {
if (currentHardwareId?.value && d.hardwareId) {
return d.hardwareId === currentHardwareId.value;
}
if (currentDeviceId?.value) {
return d.deviceId === currentDeviceId.value;
}
return false;
}
const currentBackendDevice = computed<ComputedDevice | null>(() => {
const found = devices.value.find(isCurrentDevice);
if (!found) return null;
return mapToComputedDevice(found, true);
});
const otherDevices = computed<ComputedDevice[]>(() => {
const currentId = currentBackendDevice.value?.deviceId;
return devices.value
.filter((d) => d.deviceId !== currentId)
.map((d) => mapToComputedDevice(d, false));
});
const iosDevices = computed<ComputedDevice[]>(() =>
otherDevices.value.filter((d) => d.platform === "ios"),
);
const desktopDevices = computed<ComputedDevice[]>(() =>
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,
};
}