- GET /api/magic/devices fetcht jetzt parallel listMagicDevices() + listProtectedDevices() und merged beide Quellen in eine Response. Items haben neues 'source' Feld (magic|protected). - ProtectedDevice (alter Native-DNS-Flow) wird auf gleiche Shape gemappt: label->hostname, platform->model. - Mac-App MagicDevice: source-Feld optional + resolvedSource Fallback fuer Backwards-Compat. id mit source-Prefix gegen Collisions zwischen Tabellen. - DeviceHubView Row: protected-Geraete bekommen graues 'Native-App' Badge und Hinweis 'Verwaltung in der ReBreak-App' statt Trash-Button (Release laeuft dort).
62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
import { listMagicDevices } from "../../db/devices";
|
|
import { listProtectedDevices } from "../../db/protectedDevices";
|
|
import { requireUser } from "../../utils/auth";
|
|
|
|
/**
|
|
* GET /api/magic/devices
|
|
*
|
|
* Listet alle gesch\u00fctzten Ger\u00e4te des Users f\u00fcr den Magic-Hub. Vereinigt:
|
|
* - Magic-Bindings (UserDevice.magicEnrolledAt) \u2014 via Magic-App registriert
|
|
* - ProtectedDevices \u2014 alter Native-App-DNS-Schutz-Flow (Multi-Device)
|
|
*
|
|
* Response-Items haben ein `source`-Flag:
|
|
* "magic" \u2192 voll verwaltet, unterst\u00fctzt request-release
|
|
* "protected" \u2192 alter Flow, nur Anzeige + revoke (TODO: own action)
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event);
|
|
|
|
const [magic, protectedDevices] = await Promise.all([
|
|
listMagicDevices(user.id),
|
|
listProtectedDevices(user.id),
|
|
]);
|
|
|
|
const magicItems = magic.map((d) => {
|
|
let releaseAvailableAt: string | null = null;
|
|
if (d.releaseRequestedAt) {
|
|
const availableAt = new Date(
|
|
d.releaseRequestedAt.getTime() + 24 * 60 * 60 * 1000,
|
|
);
|
|
releaseAvailableAt = availableAt.toISOString();
|
|
}
|
|
|
|
return {
|
|
source: "magic" as const,
|
|
deviceId: d.deviceId,
|
|
hostname: d.hostname ?? "Unbenanntes Ger\u00e4t",
|
|
model: d.model,
|
|
osVersion: d.osVersion,
|
|
magicEnrolledAt: d.magicEnrolledAt.toISOString(),
|
|
releaseRequestedAt: d.releaseRequestedAt?.toISOString() ?? null,
|
|
releaseAvailableAt,
|
|
};
|
|
});
|
|
|
|
const protectedItems = protectedDevices.map((d) => ({
|
|
source: "protected" as const,
|
|
deviceId: d.id,
|
|
hostname: d.label,
|
|
model: d.platform,
|
|
osVersion: null as string | null,
|
|
magicEnrolledAt: (d.installedAt ?? d.createdAt).toISOString(),
|
|
releaseRequestedAt: null as string | null,
|
|
releaseAvailableAt: null as string | null,
|
|
}));
|
|
|
|
// Magic-Bindings zuerst (neuste), dann alte ProtectedDevices
|
|
return {
|
|
success: true,
|
|
data: [...magicItems, ...protectedItems],
|
|
};
|
|
});
|