forked from baron/baron-sso
fix(headless-login): show full parsed jwks key values
- return the full RSA n value in parsedKeys responses - render parsed key fields with labels and multiline key material in DevFront - lock the behavior with backend and Playwright regression tests
This commit is contained in:
@@ -1313,35 +1313,55 @@ function ClientGeneralPage() {
|
||||
</p>
|
||||
</div>
|
||||
{currentHeadlessJwksCache.parsedKeys?.length ? (
|
||||
<div className="grid gap-3 lg:grid-cols-2">
|
||||
<div className="space-y-3">
|
||||
{currentHeadlessJwksCache.parsedKeys.map((key, index) => (
|
||||
<div
|
||||
key={`${key.kid || "key"}-${index}`}
|
||||
className="rounded-xl border border-border bg-muted/30 p-3"
|
||||
>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Badge variant="secondary" className="font-mono">
|
||||
{key.kid || "-"}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="font-mono">
|
||||
{key.kty || "-"}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="font-mono">
|
||||
{key.use || "-"}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="font-mono">
|
||||
{key.alg || "-"}
|
||||
</Badge>
|
||||
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
KID
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.kid || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
KTY
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.kty || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
USE
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.use || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
ALG
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.alg || "-"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
{t(
|
||||
"ui.dev.clients.general.public_key.cache.parsed_key_n",
|
||||
"n Preview",
|
||||
"N",
|
||||
)}
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.nPreview || "-"}
|
||||
<p className="min-h-16 break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px] leading-5">
|
||||
{key.n || "-"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,7 +80,7 @@ export type ClientDetailResponse = {
|
||||
kty?: string;
|
||||
use?: string;
|
||||
alg?: string;
|
||||
nPreview?: string;
|
||||
n?: string;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -149,8 +149,8 @@ test.describe("DevFront clients lifecycle", () => {
|
||||
kty: "RSA",
|
||||
use: "sig",
|
||||
alg: "RS256",
|
||||
nPreview:
|
||||
"voVbHlo_UHkj...Hb8PiTCQ",
|
||||
n:
|
||||
"voVbHlo_UHkjtT7Q_8owyjZ2omE8n8mbGlpraZziStHPfe08q_RGiEXO6Pyiz42NVi-Yo0c7qiaqRwB4h9s5phpT2wwcUxnkrQeRhe7BpigInZPzpwq1hsaB2zyhE7zTRCC3hinGtFdVpNzTVKYKGPbXfeEXaRL3P838vi-_iB4IN3WQk_pAakUQvajL2H-vcWSMSNslMGPDZxobqE9MHSWocNXemrcmtCeE7ruUND0qHZOb8k-hHUBqsNoJ63WKdapzGYF6e2qgDRveYrjgOCBigZPi8npN0xStQ0YcrH_RxeTogsdRZ8SuXmLqavryVDnrT8czPkkJ-EHb8PiTCQ",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -211,6 +211,7 @@ test.describe("DevFront clients lifecycle", () => {
|
||||
page.getByText(/cached at|캐시됨|last refresh|마지막 갱신/i),
|
||||
).toBeVisible();
|
||||
await expect(page.getByText(/Parsed Keys|파싱된 키/i)).toBeVisible();
|
||||
await expect(page.getByText(/^KID$/i)).toBeVisible();
|
||||
await expect(page.getByText("kid-1", { exact: true }).last()).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(/Allowed algorithms|허용 알고리즘/i),
|
||||
@@ -230,7 +231,10 @@ test.describe("DevFront clients lifecycle", () => {
|
||||
await expect(page.getByText(algorithm, { exact: true }).last()).toBeVisible();
|
||||
}
|
||||
await expect(
|
||||
page.getByText("voVbHlo_UHkj...Hb8PiTCQ", { exact: true }),
|
||||
page.getByText(
|
||||
"voVbHlo_UHkjtT7Q_8owyjZ2omE8n8mbGlpraZziStHPfe08q_RGiEXO6Pyiz42NVi-Yo0c7qiaqRwB4h9s5phpT2wwcUxnkrQeRhe7BpigInZPzpwq1hsaB2zyhE7zTRCC3hinGtFdVpNzTVKYKGPbXfeEXaRL3P838vi-_iB4IN3WQk_pAakUQvajL2H-vcWSMSNslMGPDZxobqE9MHSWocNXemrcmtCeE7ruUND0qHZOb8k-hHUBqsNoJ63WKdapzGYF6e2qgDRveYrjgOCBigZPi8npN0xStQ0YcrH_RxeTogsdRZ8SuXmLqavryVDnrT8czPkkJ-EHb8PiTCQ",
|
||||
{ exact: true },
|
||||
),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("button", { name: /refresh|새로고침/i }),
|
||||
|
||||
@@ -33,7 +33,7 @@ export type Client = {
|
||||
kty?: string;
|
||||
use?: string;
|
||||
alg?: string;
|
||||
nPreview?: string;
|
||||
n?: string;
|
||||
}>;
|
||||
};
|
||||
metadata?: Record<string, unknown>;
|
||||
|
||||
Reference in New Issue
Block a user