1
0
forked from baron/baron-sso

스코프 순서 및 테넌트 검색 수정

This commit is contained in:
2026-04-24 17:18:47 +09:00
parent 373751996a
commit b9232687b5
2 changed files with 36 additions and 24 deletions

View File

@@ -34,7 +34,7 @@ import {
createClient, createClient,
deleteClient, deleteClient,
fetchClient, fetchClient,
fetchTenants, fetchMyTenants,
refreshHeadlessJwksCache, refreshHeadlessJwksCache,
revokeHeadlessJwksCache, revokeHeadlessJwksCache,
updateClient, updateClient,
@@ -44,6 +44,7 @@ import type {
ClientStatus, ClientStatus,
ClientType, ClientType,
ClientUpsertRequest, ClientUpsertRequest,
MyTenantSummary,
TenantSummary, TenantSummary,
} from "../../lib/devApi"; } from "../../lib/devApi";
import { t } from "../../lib/i18n"; import { t } from "../../lib/i18n";
@@ -138,8 +139,8 @@ function ClientGeneralPage() {
enabled: !isCreate, enabled: !isCreate,
}); });
const { data: tenantData } = useQuery({ const { data: tenantData } = useQuery({
queryKey: ["tenants"], queryKey: ["my-tenants"],
queryFn: () => fetchTenants(1000, 0), queryFn: fetchMyTenants,
}); });
const [name, setName] = useState(""); const [name, setName] = useState("");
@@ -172,18 +173,6 @@ function ClientGeneralPage() {
}, },
{ {
id: "2", id: "2",
name: "profile",
description: t("msg.dev.clients.scopes.profile", "기본 프로필 정보 접근"),
mandatory: false,
},
{
id: "3",
name: "email",
description: t("msg.dev.clients.scopes.email", "이메일 주소 접근"),
mandatory: false,
},
{
id: "4",
name: "tenant", name: "tenant",
description: t( description: t(
"msg.dev.clients.scopes.tenant", "msg.dev.clients.scopes.tenant",
@@ -191,6 +180,18 @@ function ClientGeneralPage() {
), ),
mandatory: false, mandatory: false,
}, },
{
id: "3",
name: "profile",
description: t("msg.dev.clients.scopes.profile", "기본 프로필 정보 접근"),
mandatory: false,
},
{
id: "4",
name: "email",
description: t("msg.dev.clients.scopes.email", "이메일 주소 접근"),
mandatory: false,
},
]); ]);
useEffect(() => { useEffect(() => {
@@ -355,7 +356,18 @@ function ClientGeneralPage() {
normalized.push(buildTenantScope(`tenant-${Date.now()}`)); normalized.push(buildTenantScope(`tenant-${Date.now()}`));
} }
return normalized; const openidScopes = normalized.filter(
(scope) => scope.name.trim() === "openid",
);
const tenantScopes = normalized.filter(
(scope) => scope.name.trim() === "tenant",
);
const remainingScopes = normalized.filter((scope) => {
const name = scope.name.trim();
return name !== "openid" && name !== "tenant";
});
return [...openidScopes, ...tenantScopes, ...remainingScopes];
} }
const handleTenantAccessToggle = (enabled: boolean) => { const handleTenantAccessToggle = (enabled: boolean) => {
@@ -514,12 +526,13 @@ function ClientGeneralPage() {
const hasValidationErrors = validationErrors.length > 0; const hasValidationErrors = validationErrors.length > 0;
const normalizedTenantSearch = tenantSearch.trim().toLowerCase(); const normalizedTenantSearch = tenantSearch.trim().toLowerCase();
const tenantOptions: TenantSummary[] = tenantData?.items ?? []; const tenantOptions: Array<TenantSummary | MyTenantSummary> = tenantData ?? [];
const filteredTenants = tenantOptions.filter((tenant) => { const filteredTenants = tenantOptions.filter((tenant) => {
if (!normalizedTenantSearch) { if (!normalizedTenantSearch) {
return true; return true;
} }
const searchable = `${tenant.name} ${tenant.slug} ${tenant.description} ${tenant.type}`.toLowerCase(); const searchable =
`${tenant.name} ${tenant.slug} ${tenant.description ?? ""} ${tenant.type ?? ""}`.toLowerCase();
return searchable.includes(normalizedTenantSearch); return searchable.includes(normalizedTenantSearch);
}); });
const tenantSuggestions = filteredTenants const tenantSuggestions = filteredTenants
@@ -527,7 +540,9 @@ function ClientGeneralPage() {
.slice(0, 8); .slice(0, 8);
const selectedAllowedTenants = allowedTenantIds const selectedAllowedTenants = allowedTenantIds
.map((tenantId) => tenantOptions.find((item) => item.id === tenantId)) .map((tenantId) => tenantOptions.find((item) => item.id === tenantId))
.filter((tenant): tenant is TenantSummary => tenant != null); .filter(
(tenant): tenant is TenantSummary | MyTenantSummary => tenant != null,
);
const refreshHeadlessJwksCacheMutation = useMutation({ const refreshHeadlessJwksCacheMutation = useMutation({
mutationFn: async () => { mutationFn: async () => {

View File

@@ -409,11 +409,8 @@ export async function fetchDevAuditLogs(
return data; return data;
} }
export type MyTenantSummary = { export type MyTenantSummary = Pick<TenantSummary, "id" | "name" | "slug"> &
id: string; Partial<TenantSummary>;
name: string;
slug: string;
};
export async function fetchMyTenants() { export async function fetchMyTenants() {
const { data } = await apiClient.get<MyTenantSummary[]>("/dev/my-tenants"); const { data } = await apiClient.get<MyTenantSummary[]>("/dev/my-tenants");