1
0
forked from baron/baron-sso
Files
baron-sso/devfront/src/components/common/ForbiddenMessage.tsx

68 lines
2.6 KiB
TypeScript

import { ShieldAlert } from "lucide-react";
import { useAuth } from "react-oidc-context";
import { t } from "../../lib/i18n";
import { resolveProfileRole } from "../../lib/role";
interface Props {
resourceToken: "audit" | "clients" | "consents";
}
export function ForbiddenMessage({ resourceToken }: Props) {
const auth = useAuth();
const rawProfile = auth.user?.profile as Record<string, unknown> | undefined;
const role = resolveProfileRole(rawProfile);
let explanation = t(
"msg.dev.forbidden.default",
"You do not have permission to access this resource. Contact your administrator.",
);
if (role === "rp_admin") {
explanation = t(
"msg.dev.forbidden.rp_admin",
"RP administrators can only access resources for their assigned applications.",
);
} else if (role === "tenant_admin") {
explanation = t(
"msg.dev.forbidden.tenant_admin",
"Your tenant administrator permission is missing, misconfigured, or expired.",
);
} else if (role === "user" || role === "tenant_member") {
if (resourceToken === "consents") {
explanation = t(
"msg.dev.forbidden.user.consents",
"Viewing consent records for this application requires an RP administrator, consent read, or consent revoke relationship. Request access from an administrator if needed.",
);
} else if (resourceToken === "audit") {
explanation = t(
"msg.dev.forbidden.user.audit",
"Viewing audit logs for this application requires an RP administrator or audit read relationship. Request access from an administrator if needed.",
);
} else {
explanation = t(
"msg.dev.forbidden.user.clients",
"Standard user accounts can use this feature only when an operational or administrative relationship is granted for the target RP. Request access from an administrator if needed.",
);
}
}
const resourceLabel =
resourceToken === "audit"
? t("ui.dev.audit.title", "Audit Logs")
: resourceToken === "consents"
? t("ui.dev.clients.consents.title", "User Consent Grants")
: t("ui.dev.clients.registry.subtitle", "Connected Applications");
const title = t("msg.dev.forbidden.title", "Access denied: {{resource}}", {
resource: resourceLabel,
});
return (
<div className="flex flex-col items-center justify-center p-12 text-center text-red-500/90 gap-3">
<ShieldAlert className="h-10 w-10 text-red-500/80 mb-2" />
<h3 className="text-xl font-bold text-foreground">{title}</h3>
<p className="text-sm text-muted-foreground max-w-md">{explanation}</p>
</div>
);
}