Files
NianAIGC/lib/server/auth/platform-session.ts

106 lines
3.4 KiB
TypeScript

import type { AuthSession, AuthUser } from "@/lib/auth/session";
import type { PlatformRole } from "@/lib/types";
export type PlatformAuthorizationAccount = {
id: string;
phone: string;
displayName: string;
role: string;
organizationId?: string;
status: string;
sessionVersion: number;
};
export type PlatformAuthorizationOrganization = {
id: string;
name: string;
status: string;
};
export type PlatformAuthorizationSnapshot = {
account: PlatformAuthorizationAccount;
organization: PlatformAuthorizationOrganization | null;
};
export type PlatformSessionAuthorizationResult =
| { outcome: "authenticated"; session: AuthSession }
| { outcome: "unauthenticated"; reason: PlatformSessionRejectionReason };
export type PlatformSessionRejectionReason =
| "client_mismatch"
| "account_not_found"
| "account_disabled"
| "invalid_role"
| "session_version_mismatch"
| "organization_required"
| "organization_not_active";
export type PlatformAuthorizationLoader = (
accountId: string,
) => PlatformAuthorizationSnapshot | null | Promise<PlatformAuthorizationSnapshot | null>;
export async function authorizePlatformSession(
session: AuthSession,
loadSnapshot: PlatformAuthorizationLoader,
requiredClientId = "platform",
): Promise<PlatformSessionAuthorizationResult> {
if (session.user.clientId !== requiredClientId) {
return { outcome: "unauthenticated", reason: "client_mismatch" };
}
const snapshot = await loadSnapshot(session.user.id);
if (!snapshot) return { outcome: "unauthenticated", reason: "account_not_found" };
const { account, organization } = snapshot;
if (account.status !== "active") {
return { outcome: "unauthenticated", reason: "account_disabled" };
}
if (session.sessionVersion && session.sessionVersion !== account.sessionVersion) {
return { outcome: "unauthenticated", reason: "session_version_mismatch" };
}
if (!isPlatformRole(account.role)) {
return { outcome: "unauthenticated", reason: "invalid_role" };
}
if (account.role !== "super_admin") {
if (!account.organizationId) {
return { outcome: "unauthenticated", reason: "organization_required" };
}
if (!organization || organization.id !== account.organizationId || organization.status !== "active") {
return { outcome: "unauthenticated", reason: "organization_not_active" };
}
}
return {
outcome: "authenticated",
session: {
...session,
authMode: account.role === "user" ? "user" : "admin",
sessionVersion: account.sessionVersion,
user: {
id: account.id,
subject: account.id,
username: account.phone,
phone: account.phone,
displayName: account.displayName,
clientId: requiredClientId,
organizationId: account.organizationId,
organizationName: organization?.name,
role: account.role,
status: "active",
authorities: authoritiesForRole(account.role),
scope: [],
},
},
};
}
function isPlatformRole(role: string): role is PlatformRole {
return role === "user" || role === "organization_admin" || role === "super_admin";
}
function authoritiesForRole(role: PlatformRole): AuthUser["authorities"] {
if (role === "super_admin") return ["ROLE_SUPER_ADMIN", "SUPER_ADMIN"];
if (role === "organization_admin") return ["ROLE_ORGANIZATION_ADMIN", "ORGANIZATION_ADMIN"];
return ["ROLE_USER"];
}