Sync safe realm-role fallback for Media Intelligence

This commit is contained in:
Admin 2026-09-29 19:46:04 +00:00
parent 338f6c232a
commit 5a92a2d792

View File

@ -95,16 +95,27 @@ function roleNamesFromClaims(claims: Record<string, any>) {
export function mediaRoleFromClaims(claims: Record<string, any>): MediaRole {
const roles = roleNamesFromClaims(claims).map((role) => role.toLowerCase());
// Dedicated Media Intelligence roles always win.
if (roles.includes("media-intelligence-admin")) return "admin";
if (roles.includes("media-intelligence-editor")) return "editor";
if (roles.includes("media-intelligence-viewer")) return "viewer";
const arrowstackRoles = roles.filter((role) =>
// Safe fallback: use only realm-level Arrowstack roles, never generic
// resource/client roles from unrelated applications.
const realmRoles = Array.isArray(claims?.realm_access?.roles)
? claims.realm_access.roles.map((role: unknown) => String(role).toLowerCase())
: [];
if (realmRoles.includes("owner") || realmRoles.includes("admin")) return "admin";
if (realmRoles.includes("operator") || realmRoles.includes("developer")) return "editor";
if (realmRoles.includes("viewer")) return "viewer";
const arrowstackRoles = realmRoles.filter((role: string) =>
role.startsWith("arrowstack-") || role.startsWith("arrowstack_")
);
if (arrowstackRoles.some((role) => /(owner|admin)$/.test(role))) return "admin";
if (arrowstackRoles.some((role) => /(operator|developer)$/.test(role))) return "editor";
if (arrowstackRoles.some((role) => /viewer$/.test(role))) return "viewer";
if (arrowstackRoles.some((role: string) => /(owner|admin)$/.test(role))) return "admin";
if (arrowstackRoles.some((role: string) => /(operator|developer)$/.test(role))) return "editor";
if (arrowstackRoles.some((role: string) => /viewer$/.test(role))) return "viewer";
// Fail safe: authenticated users with no recognised mapping can read but not mutate.
return "viewer";