69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
/**
|
||
* JIT-Provisioning (platform-plan.md §3.2):
|
||
* Koppelt einen Hub-User an einen lokalen Kalendartool-Account.
|
||
*
|
||
* - Existiert bereits ein Account mit dieser hubId → zurückgeben.
|
||
* - Existiert ein Account mit gleicher E-Mail (lokaler Login) → koppeln
|
||
* (hubId setzen), Passwort/Rolle bleiben unangetastet.
|
||
* - Sonst → neuen Account anlegen (Default-Rolle USER, kein Passwort).
|
||
*
|
||
* Bewusst KEINE Rollen-Synchronisation: Der Kalendertool-Admin verwaltet
|
||
* Rollen weiterhin selbst (Hub entscheidet nur über Tool-Zugriff).
|
||
*/
|
||
import { prisma } from "@/lib/db/client";
|
||
import type { AuthenticatedUser } from "@/lib/permissions/permissions";
|
||
import type { Role } from "@prisma/client";
|
||
|
||
export interface HubIdentity {
|
||
hubId: string;
|
||
email: string;
|
||
name: string;
|
||
isAdmin: boolean;
|
||
}
|
||
|
||
export async function provisionHubUser(identity: HubIdentity): Promise<AuthenticatedUser> {
|
||
// 1. Bereits gekoppelt?
|
||
const byHubId = await prisma.user.findUnique({ where: { hubId: identity.hubId } });
|
||
if (byHubId) {
|
||
return {
|
||
id: byHubId.id,
|
||
email: byHubId.email,
|
||
username: byHubId.username,
|
||
role: byHubId.role,
|
||
};
|
||
}
|
||
|
||
// 2. Gleiche E-Mail vorhanden (lokaler Account) → koppeln.
|
||
const byEmail = await prisma.user.findUnique({ where: { email: identity.email } });
|
||
if (byEmail) {
|
||
const linked = await prisma.user.update({
|
||
where: { id: byEmail.id },
|
||
data: { hubId: identity.hubId },
|
||
});
|
||
return {
|
||
id: linked.id,
|
||
email: linked.email,
|
||
username: linked.username,
|
||
role: linked.role,
|
||
};
|
||
}
|
||
|
||
// 3. Neuen Account anlegen (JIT). Kein Passwort – Login nur via Hub.
|
||
const created = await prisma.user.create({
|
||
data: {
|
||
email: identity.email,
|
||
username: identity.name || null,
|
||
// passwordHash ist NOT NULL → nicht ratbares Zufallspasswort.
|
||
passwordHash: crypto.randomUUID() + crypto.randomUUID(),
|
||
role: "USER" as Role,
|
||
hubId: identity.hubId,
|
||
},
|
||
});
|
||
|
||
return {
|
||
id: created.id,
|
||
email: created.email,
|
||
username: created.username,
|
||
role: created.role,
|
||
};
|
||
} |