forked from baron/baron-sso
devfront 설정 화면 로케일 누락 수정
This commit is contained in:
@@ -1178,14 +1178,14 @@ function ClientGeneralPage() {
|
|||||||
if (!trimmedJwksUri) {
|
if (!trimmedJwksUri) {
|
||||||
validationErrors.push(
|
validationErrors.push(
|
||||||
t(
|
t(
|
||||||
"msg.dev.clients.general.public_key.validation.missing_jwks_uri",
|
"ui.dev.clients.general.public_key.validation.missing_jwks_uri",
|
||||||
"JWKS URI를 입력해야 합니다.",
|
"JWKS URI를 입력해야 합니다.",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (!isValidUrl(trimmedJwksUri)) {
|
} else if (!isValidUrl(trimmedJwksUri)) {
|
||||||
validationErrors.push(
|
validationErrors.push(
|
||||||
t(
|
t(
|
||||||
"msg.dev.clients.general.public_key.validation.invalid_jwks_uri",
|
"ui.dev.clients.general.public_key.validation.invalid_jwks_uri",
|
||||||
"JWKS URI 형식이 올바르지 않습니다.",
|
"JWKS URI 형식이 올바르지 않습니다.",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1193,7 +1193,7 @@ function ClientGeneralPage() {
|
|||||||
if (unsupportedParsedAlgorithms.length > 0) {
|
if (unsupportedParsedAlgorithms.length > 0) {
|
||||||
validationErrors.push(
|
validationErrors.push(
|
||||||
t(
|
t(
|
||||||
"msg.dev.clients.general.public_key.validation.unsupported_parsed_algorithms",
|
"ui.dev.clients.general.public_key.validation.unsupported_parsed_algorithms",
|
||||||
"JWKS에 지원하지 않는 알고리즘이 있습니다: {{details}}",
|
"JWKS에 지원하지 않는 알고리즘이 있습니다: {{details}}",
|
||||||
{ details: unsupportedParsedAlgorithmSummary },
|
{ details: unsupportedParsedAlgorithmSummary },
|
||||||
),
|
),
|
||||||
@@ -1202,7 +1202,7 @@ function ClientGeneralPage() {
|
|||||||
if (missingParsedAlgorithms.length > 0) {
|
if (missingParsedAlgorithms.length > 0) {
|
||||||
validationErrors.push(
|
validationErrors.push(
|
||||||
t(
|
t(
|
||||||
"msg.dev.clients.general.public_key.validation.missing_parsed_algorithms",
|
"ui.dev.clients.general.public_key.validation.missing_parsed_algorithms",
|
||||||
"JWKS에 알고리즘(`alg`)이 선언되지 않은 키가 있습니다: {{details}}",
|
"JWKS에 알고리즘(`alg`)이 선언되지 않은 키가 있습니다: {{details}}",
|
||||||
{ details: missingParsedAlgorithmSummary },
|
{ details: missingParsedAlgorithmSummary },
|
||||||
),
|
),
|
||||||
@@ -2050,13 +2050,13 @@ function ClientGeneralPage() {
|
|||||||
<p className="text-sm font-semibold">
|
<p className="text-sm font-semibold">
|
||||||
{t(
|
{t(
|
||||||
"ui.dev.clients.general.scopes.picker_title",
|
"ui.dev.clients.general.scopes.picker_title",
|
||||||
"추가할 scope 선택",
|
"Add a scope",
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">
|
||||||
{t(
|
{t(
|
||||||
"msg.dev.clients.general.scopes.picker_help",
|
"ui.dev.clients.general.scopes.picker_help",
|
||||||
"지원 scope와 Custom Claim key를 선택해 scope 목록에 추가합니다.",
|
"Choose a supported scope or custom claim key to add it to the scope list.",
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -2427,13 +2427,13 @@ function ClientGeneralPage() {
|
|||||||
{tenantAccessRestricted ? (
|
{tenantAccessRestricted ? (
|
||||||
<div className="grid gap-4 lg:grid-cols-[0.8fr_1.2fr]">
|
<div className="grid gap-4 lg:grid-cols-[0.8fr_1.2fr]">
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<Label className="text-sm font-semibold">
|
<Label className="text-sm font-semibold">
|
||||||
{t(
|
{t(
|
||||||
"ui.dev.clients.general.tenant_access.picker_label",
|
"ui.dev.clients.general.tenant_access.picker_label",
|
||||||
"허용 테넌트 추가",
|
"Add allowed tenant",
|
||||||
)}{" "}
|
)}{" "}
|
||||||
<span className="text-destructive">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<TenantAccessPicker
|
<TenantAccessPicker
|
||||||
disabled={isGeneralSettingsReadOnly}
|
disabled={isGeneralSettingsReadOnly}
|
||||||
selectedCount={allowedTenantIds.length}
|
selectedCount={allowedTenantIds.length}
|
||||||
@@ -3069,8 +3069,8 @@ function ClientGeneralPage() {
|
|||||||
</Label>
|
</Label>
|
||||||
<p className="text-[10px] text-muted-foreground">
|
<p className="text-[10px] text-muted-foreground">
|
||||||
{t(
|
{t(
|
||||||
"msg.dev.clients.general.security.headless_login_enable_help",
|
"ui.dev.clients.general.security.headless_login_enable_help",
|
||||||
"Baron SSO 로그인 창 대신 RP 자체 로그인 UI를 사용하고, RP backend의 서명 키로 클라이언트를 검증하려는 경우 활성화합니다.",
|
"Enable this when the RP uses its own login UI instead of the Baron SSO login page and the RP backend validates the client with a signing key.",
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export function TenantAccessPicker({
|
|||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
aria-label={t(
|
aria-label={t(
|
||||||
"ui.dev.clients.general.tenant_access.picker_title",
|
"ui.dev.clients.general.tenant_access.picker_title",
|
||||||
"테넌트 선택",
|
"Select tenant",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex h-[92vh] w-[min(96vw,1200px)] flex-col overflow-hidden rounded-2xl border border-border bg-background p-4 shadow-2xl">
|
<div className="flex h-[92vh] w-[min(96vw,1200px)] flex-col overflow-hidden rounded-2xl border border-border bg-background p-4 shadow-2xl">
|
||||||
@@ -66,13 +66,13 @@ export function TenantAccessPicker({
|
|||||||
<h2 className="text-lg font-semibold">
|
<h2 className="text-lg font-semibold">
|
||||||
{t(
|
{t(
|
||||||
"ui.dev.clients.general.tenant_access.picker_title",
|
"ui.dev.clients.general.tenant_access.picker_title",
|
||||||
"테넌트 선택",
|
"Select tenant",
|
||||||
)}
|
)}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
{t(
|
{t(
|
||||||
"msg.dev.clients.general.tenant_access.picker_description",
|
"ui.dev.clients.general.tenant_access.picker_description",
|
||||||
"orgfront 조직도에서 허용할 테넌트를 선택하면 목록에 추가됩니다.",
|
"Choose the tenants to allow from the orgfront org chart and add them to the list.",
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,7 +83,7 @@ export function TenantAccessPicker({
|
|||||||
className="shrink-0"
|
className="shrink-0"
|
||||||
onClick={() => setPickerOpen(false)}
|
onClick={() => setPickerOpen(false)}
|
||||||
>
|
>
|
||||||
{t("ui.common.close", "닫기")}
|
{t("ui.common.close", "Close")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 min-h-0 flex-1 overflow-hidden rounded-md border">
|
<div className="mt-4 min-h-0 flex-1 overflow-hidden rounded-md border">
|
||||||
@@ -102,7 +102,7 @@ export function TenantAccessPicker({
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => setPickerOpen(false)}
|
onClick={() => setPickerOpen(false)}
|
||||||
>
|
>
|
||||||
{t("ui.common.close", "닫기")}
|
{t("ui.common.close", "Close")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -123,7 +123,7 @@ export function TenantAccessPicker({
|
|||||||
<Building2 className="h-4 w-4" />
|
<Building2 className="h-4 w-4" />
|
||||||
{t(
|
{t(
|
||||||
"ui.dev.clients.general.tenant_access.open_picker",
|
"ui.dev.clients.general.tenant_access.open_picker",
|
||||||
"테넌트 선택기 열기",
|
"Open tenant picker",
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
@@ -132,13 +132,13 @@ export function TenantAccessPicker({
|
|||||||
<div className="rounded-xl border border-dashed border-border bg-muted/20 px-4 py-3 text-sm text-muted-foreground">
|
<div className="rounded-xl border border-dashed border-border bg-muted/20 px-4 py-3 text-sm text-muted-foreground">
|
||||||
{selectedCount > 0
|
{selectedCount > 0
|
||||||
? t(
|
? t(
|
||||||
"msg.dev.clients.general.tenant_access.picker_hint_with_count",
|
"ui.dev.clients.general.tenant_access.picker_hint_with_count",
|
||||||
"현재 {{count}}개가 선택되어 있습니다.",
|
"{{count}} tenants selected.",
|
||||||
{ count: selectedCount },
|
{ count: selectedCount },
|
||||||
)
|
)
|
||||||
: t(
|
: t(
|
||||||
"msg.dev.clients.general.tenant_access.picker_hint",
|
"ui.dev.clients.general.tenant_access.picker_hint",
|
||||||
"선택기를 열어 허용 테넌트를 추가하세요.",
|
"Open the picker to add allowed tenants.",
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||||
import { normalizeDeveloperAccessPageSelection } from "./developerAccessPages";
|
import {
|
||||||
|
developerAccessPagesToLabel,
|
||||||
|
getDeveloperAccessPageLabel,
|
||||||
|
normalizeDeveloperAccessPageSelection,
|
||||||
|
} from "./developerAccessPages";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
window.localStorage.clear();
|
||||||
|
window.localStorage.setItem("locale", "ko");
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
window.localStorage.clear();
|
||||||
|
});
|
||||||
|
|
||||||
describe("developer access pages", () => {
|
describe("developer access pages", () => {
|
||||||
it("collapses all non-all pages into all", () => {
|
it("collapses all non-all pages into all", () => {
|
||||||
@@ -21,4 +34,20 @@ describe("developer access pages", () => {
|
|||||||
it("keeps explicit all selection", () => {
|
it("keeps explicit all selection", () => {
|
||||||
expect(normalizeDeveloperAccessPageSelection(["all"])).toEqual(["all"]);
|
expect(normalizeDeveloperAccessPageSelection(["all"])).toEqual(["all"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("returns localized labels for access pages", () => {
|
||||||
|
expect(getDeveloperAccessPageLabel("all")).toBe("전체");
|
||||||
|
expect(developerAccessPagesToLabel(["overview", "audit"])).toBe(
|
||||||
|
"개요, 감사로그",
|
||||||
|
);
|
||||||
|
|
||||||
|
window.localStorage.setItem("locale", "en");
|
||||||
|
|
||||||
|
expect(getDeveloperAccessPageLabel("client_create")).toBe(
|
||||||
|
"Add linked app",
|
||||||
|
);
|
||||||
|
expect(developerAccessPagesToLabel(["overview", "audit"])).toBe(
|
||||||
|
"Overview, Audit Logs",
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { t } from "../../lib/i18n";
|
||||||
|
|
||||||
export type DeveloperAccessPage =
|
export type DeveloperAccessPage =
|
||||||
| "all"
|
| "all"
|
||||||
| "overview"
|
| "overview"
|
||||||
@@ -10,15 +12,40 @@ export const developerAccessPageOrder: DeveloperAccessPage[] = [
|
|||||||
"audit",
|
"audit",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const developerAccessPageOptions: Array<{
|
export function getDeveloperAccessPageLabel(page: DeveloperAccessPage): string {
|
||||||
|
switch (page) {
|
||||||
|
case "all":
|
||||||
|
return t("ui.dev.access_pages.all", "전체");
|
||||||
|
case "overview":
|
||||||
|
return t("ui.dev.access_pages.overview", "개요");
|
||||||
|
case "client_create":
|
||||||
|
return t("ui.dev.access_pages.client_create", "연동 앱 추가");
|
||||||
|
case "audit":
|
||||||
|
return t("ui.dev.access_pages.audit", "감사로그");
|
||||||
|
default:
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDeveloperAccessPageOptions(): Array<{
|
||||||
value: DeveloperAccessPage;
|
value: DeveloperAccessPage;
|
||||||
label: string;
|
label: string;
|
||||||
}> = [
|
}> {
|
||||||
{ value: "all", label: "전체" },
|
return developerAccessPageOrder.length > 0
|
||||||
{ value: "overview", label: "개요" },
|
? [
|
||||||
{ value: "client_create", label: "연동 앱 추가" },
|
{ value: "all", label: getDeveloperAccessPageLabel("all") },
|
||||||
{ value: "audit", label: "감사로그" },
|
{
|
||||||
];
|
value: "overview",
|
||||||
|
label: getDeveloperAccessPageLabel("overview"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "client_create",
|
||||||
|
label: getDeveloperAccessPageLabel("client_create"),
|
||||||
|
},
|
||||||
|
{ value: "audit", label: getDeveloperAccessPageLabel("audit") },
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
}
|
||||||
|
|
||||||
export function normalizeDeveloperAccessPages(
|
export function normalizeDeveloperAccessPages(
|
||||||
pages: Array<string | undefined | null>,
|
pages: Array<string | undefined | null>,
|
||||||
@@ -61,20 +88,11 @@ export function normalizeDeveloperAccessPageSelection(
|
|||||||
export function developerAccessPagesToLabel(pages?: Array<string | null>) {
|
export function developerAccessPagesToLabel(pages?: Array<string | null>) {
|
||||||
const normalized = normalizeDeveloperAccessPages(pages ?? []);
|
const normalized = normalizeDeveloperAccessPages(pages ?? []);
|
||||||
if (normalized.length === 0 || normalized.includes("all")) {
|
if (normalized.length === 0 || normalized.includes("all")) {
|
||||||
return "전체";
|
return getDeveloperAccessPageLabel("all");
|
||||||
}
|
}
|
||||||
return normalized
|
return normalized
|
||||||
.map((page) => {
|
.map((page) => {
|
||||||
switch (page) {
|
return getDeveloperAccessPageLabel(page);
|
||||||
case "overview":
|
|
||||||
return "개요";
|
|
||||||
case "client_create":
|
|
||||||
return "연동 앱 추가";
|
|
||||||
case "audit":
|
|
||||||
return "감사로그";
|
|
||||||
default:
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.join(", ");
|
.join(", ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ import { resolveProfileRole } from "../../lib/role";
|
|||||||
import { fetchMe } from "../auth/authApi";
|
import { fetchMe } from "../auth/authApi";
|
||||||
import {
|
import {
|
||||||
type DeveloperAccessPage,
|
type DeveloperAccessPage,
|
||||||
developerAccessPageOptions,
|
developerAccessPagesToLabel,
|
||||||
|
getDeveloperAccessPageOptions,
|
||||||
normalizeDeveloperAccessPageSelection,
|
normalizeDeveloperAccessPageSelection,
|
||||||
normalizeDeveloperAccessPages,
|
normalizeDeveloperAccessPages,
|
||||||
} from "../developer-access/developerAccessPages";
|
} from "../developer-access/developerAccessPages";
|
||||||
@@ -62,6 +63,7 @@ export default function DeveloperGrantsPage() {
|
|||||||
});
|
});
|
||||||
const profileRole = me?.role?.trim() || role;
|
const profileRole = me?.role?.trim() || role;
|
||||||
const isSuperAdmin = profileRole === "super_admin";
|
const isSuperAdmin = profileRole === "super_admin";
|
||||||
|
const developerAccessPageOptions = getDeveloperAccessPageOptions();
|
||||||
|
|
||||||
const [userSearch, setUserSearch] = useState("");
|
const [userSearch, setUserSearch] = useState("");
|
||||||
const deferredUserSearch = useDeferredValue(userSearch.trim());
|
const deferredUserSearch = useDeferredValue(userSearch.trim());
|
||||||
@@ -621,9 +623,7 @@ export default function DeveloperGrantsPage() {
|
|||||||
: ["all"]
|
: ["all"]
|
||||||
).map((page) => (
|
).map((page) => (
|
||||||
<Badge key={page} variant="outline">
|
<Badge key={page} variant="outline">
|
||||||
{developerAccessPageOptions.find(
|
{developerAccessPagesToLabel([page])}
|
||||||
(option) => option.value === page,
|
|
||||||
)?.label ?? page}
|
|
||||||
</Badge>
|
</Badge>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ import { resolveProfileRole } from "../../lib/role";
|
|||||||
import { fetchMe } from "../auth/authApi";
|
import { fetchMe } from "../auth/authApi";
|
||||||
import {
|
import {
|
||||||
type DeveloperAccessPage,
|
type DeveloperAccessPage,
|
||||||
developerAccessPageOptions,
|
developerAccessPagesToLabel,
|
||||||
|
getDeveloperAccessPageOptions,
|
||||||
normalizeDeveloperAccessPageSelection,
|
normalizeDeveloperAccessPageSelection,
|
||||||
normalizeDeveloperAccessPages,
|
normalizeDeveloperAccessPages,
|
||||||
} from "../developer-access/developerAccessPages";
|
} from "../developer-access/developerAccessPages";
|
||||||
@@ -287,9 +288,7 @@ export default function DeveloperRequestPage() {
|
|||||||
req.accessPages,
|
req.accessPages,
|
||||||
).map((page) => (
|
).map((page) => (
|
||||||
<Badge key={page} variant="outline">
|
<Badge key={page} variant="outline">
|
||||||
{developerAccessPageOptions.find(
|
{developerAccessPagesToLabel([page])}
|
||||||
(option) => option.value === page,
|
|
||||||
)?.label ?? page}
|
|
||||||
</Badge>
|
</Badge>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
@@ -479,6 +478,7 @@ function RequestAccessModal({
|
|||||||
const [accessPages, setAccessPages] = useState<DeveloperAccessPage[]>([
|
const [accessPages, setAccessPages] = useState<DeveloperAccessPage[]>([
|
||||||
"all",
|
"all",
|
||||||
]);
|
]);
|
||||||
|
const developerAccessPageOptions = getDeveloperAccessPageOptions();
|
||||||
const organizationDisplay = organization.trim() || t("ui.common.na", "없음");
|
const organizationDisplay = organization.trim() || t("ui.common.na", "없음");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
29
devfront/src/lib/i18n.test.ts
Normal file
29
devfront/src/lib/i18n.test.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
|
import { t } from "./i18n";
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
window.localStorage.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("i18n", () => {
|
||||||
|
it("returns English copy for the developer request and grants screens", () => {
|
||||||
|
window.localStorage.setItem("locale", "en");
|
||||||
|
|
||||||
|
expect(t("ui.dev.request.list.title", "신청 내역")).toBe("Request History");
|
||||||
|
expect(t("msg.dev.request.list.approved_count", "총 {{count}}명의 사용자가 승인되었습니다.", { count: 0 })).toBe(
|
||||||
|
"0 users have been approved.",
|
||||||
|
);
|
||||||
|
expect(t("ui.dev.grants.form.title", "직접 부여")).toBe("Direct Grant");
|
||||||
|
expect(
|
||||||
|
t(
|
||||||
|
"msg.dev.grants.form.description",
|
||||||
|
"사용자를 선택하면 현재 소속 정보가 표시되고, 그 사용자에게 개발자 권한을 즉시 부여합니다.",
|
||||||
|
),
|
||||||
|
).toBe(
|
||||||
|
"Select a user to view their current tenant, email, and phone, then grant developer access immediately.",
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
t("msg.dev.grants.list.description", "현재 부여된 개발자 권한 목록입니다."),
|
||||||
|
).toBe("Current developer access grants.");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -321,12 +321,14 @@ admin_desc = "Manage developer access requests submitted by users."
|
|||||||
approved = "Approved."
|
approved = "Approved."
|
||||||
cancelled = "Approval has been cancelled."
|
cancelled = "Approval has been cancelled."
|
||||||
empty = "No requests found."
|
empty = "No requests found."
|
||||||
list.approved_count = "{{count}} users have been approved."
|
|
||||||
need_cancel_notes = "Please enter a reason for cancelling approval."
|
need_cancel_notes = "Please enter a reason for cancelling approval."
|
||||||
need_notes = "Please enter a rejection reason."
|
need_notes = "Please enter a rejection reason."
|
||||||
rejected = "Rejected."
|
rejected = "Rejected."
|
||||||
user_desc = "Review your request history and submit a new access request."
|
user_desc = "Review your request history and submit a new access request."
|
||||||
|
|
||||||
|
[msg.dev.request.list]
|
||||||
|
approved_count = "{{count}} users have been approved."
|
||||||
|
|
||||||
[msg.dev.request.modal]
|
[msg.dev.request.modal]
|
||||||
desc = "Please enter the reason for your request. It will be approved after administrator review."
|
desc = "Please enter the reason for your request. It will be approved after administrator review."
|
||||||
tenant_required = "Please submit a developer access request."
|
tenant_required = "Please submit a developer access request."
|
||||||
@@ -573,10 +575,8 @@ admin_notes_placeholder = "e.g. Grant access after verifying the test environmen
|
|||||||
empty = "There are no granted permissions."
|
empty = "There are no granted permissions."
|
||||||
forbidden = "Only super admin can directly grant developer access."
|
forbidden = "Only super admin can directly grant developer access."
|
||||||
forbidden_desc = "This screen is available only to super admin."
|
forbidden_desc = "This screen is available only to super admin."
|
||||||
form.description = "Select a user to view their current tenant, email, and phone, then grant developer access immediately."
|
|
||||||
selected_info_description = "Review the selected user's tenant, email, and phone."
|
selected_info_description = "Review the selected user's tenant, email, and phone."
|
||||||
user_section_description = "Enter a search term to select a user. The next-step information stays empty until a user is chosen."
|
user_section_description = "Enter a search term to select a user. The next-step information stays empty until a user is chosen."
|
||||||
list.description = "Current developer access grants."
|
|
||||||
load_error = "Failed to load developer access grants."
|
load_error = "Failed to load developer access grants."
|
||||||
reason = "Grant reason"
|
reason = "Grant reason"
|
||||||
revoke = "Revoke"
|
revoke = "Revoke"
|
||||||
@@ -588,6 +588,13 @@ tenant_required = "The selected user's tenant information is unavailable."
|
|||||||
tenant_missing = "No tenant information is available for the selected user."
|
tenant_missing = "No tenant information is available for the selected user."
|
||||||
user_required = "Select a user before granting access."
|
user_required = "Select a user before granting access."
|
||||||
phone_missing = "No phone number is registered."
|
phone_missing = "No phone number is registered."
|
||||||
|
pages_hint = "If you select All, Overview, Add linked app, and Audit Logs are all included."
|
||||||
|
|
||||||
|
[msg.dev.grants.form]
|
||||||
|
description = "Select a user to view their current tenant, email, and phone, then grant developer access immediately."
|
||||||
|
|
||||||
|
[msg.dev.grants.list]
|
||||||
|
description = "Current developer access grants."
|
||||||
|
|
||||||
[msg.dev.dashboard.notice]
|
[msg.dev.dashboard.notice]
|
||||||
consent_audit = "Consent Audit"
|
consent_audit = "Consent Audit"
|
||||||
@@ -1351,10 +1358,8 @@ admin_notes = "Grant Reason"
|
|||||||
all_tenants = "All Tenants"
|
all_tenants = "All Tenants"
|
||||||
approved = "Approved"
|
approved = "Approved"
|
||||||
date = "Granted At"
|
date = "Granted At"
|
||||||
form.title = "Direct Grant"
|
|
||||||
grant = "Grant Directly"
|
grant = "Grant Directly"
|
||||||
input_section = "Input"
|
input_section = "Input"
|
||||||
list.title = "Granted Access"
|
|
||||||
pages = "Access Pages"
|
pages = "Access Pages"
|
||||||
read_only = "Read Only"
|
read_only = "Read Only"
|
||||||
reason = "Grant Reason"
|
reason = "Grant Reason"
|
||||||
@@ -1369,6 +1374,12 @@ user_section = "User Selection"
|
|||||||
user = "User"
|
user = "User"
|
||||||
user_search_placeholder = "Search by name or email..."
|
user_search_placeholder = "Search by name or email..."
|
||||||
|
|
||||||
|
[ui.dev.grants.form]
|
||||||
|
title = "Direct Grant"
|
||||||
|
|
||||||
|
[ui.dev.grants.list]
|
||||||
|
title = "Granted Access"
|
||||||
|
|
||||||
[ui.dev.request.modal]
|
[ui.dev.request.modal]
|
||||||
email = "Email"
|
email = "Email"
|
||||||
name = "Name"
|
name = "Name"
|
||||||
@@ -1380,6 +1391,12 @@ reason_placeholder = "e.g. I need to create an OIDC client for internal service
|
|||||||
role = "Role"
|
role = "Role"
|
||||||
title = "Developer Access Request"
|
title = "Developer Access Request"
|
||||||
|
|
||||||
|
[ui.dev.access_pages]
|
||||||
|
all = "All"
|
||||||
|
overview = "Overview"
|
||||||
|
client_create = "Add linked app"
|
||||||
|
audit = "Audit Logs"
|
||||||
|
|
||||||
[ui.dev.request.status]
|
[ui.dev.request.status]
|
||||||
approved = "Approved"
|
approved = "Approved"
|
||||||
cancelled = "Approval Cancelled"
|
cancelled = "Approval Cancelled"
|
||||||
@@ -1597,6 +1614,8 @@ name_placeholder = "e.g. profile"
|
|||||||
title = "Scopes"
|
title = "Scopes"
|
||||||
offline_access_title = "offline_access scope is required when using refresh tokens."
|
offline_access_title = "offline_access scope is required when using refresh tokens."
|
||||||
offline_access_toggle = "Show details"
|
offline_access_toggle = "Show details"
|
||||||
|
picker_title = "Select a scope to add"
|
||||||
|
picker_help = "Choose a supported scope or custom claim key to add it to the scope list."
|
||||||
|
|
||||||
[ui.dev.clients.general.scopes.table]
|
[ui.dev.clients.general.scopes.table]
|
||||||
description = "Scope Description"
|
description = "Scope Description"
|
||||||
@@ -1617,6 +1636,12 @@ empty = "No tenants match your search."
|
|||||||
hint = "Turning this on adds the tenant scope automatically and requires at least one allowed tenant."
|
hint = "Turning this on adds the tenant scope automatically and requires at least one allowed tenant."
|
||||||
autocomplete_hint = "Type a tenant name to see autocomplete suggestions. Click one to add it to the allowed list."
|
autocomplete_hint = "Type a tenant name to see autocomplete suggestions. Click one to add it to the allowed list."
|
||||||
validation_required = "Select at least one allowed tenant when tenant access restriction is enabled."
|
validation_required = "Select at least one allowed tenant when tenant access restriction is enabled."
|
||||||
|
picker_title = "Select tenant"
|
||||||
|
picker_label = "Add allowed tenant"
|
||||||
|
open_picker = "Open tenant picker"
|
||||||
|
picker_description = "Choose the tenants to allow from the orgfront org chart and add them to the list."
|
||||||
|
picker_hint = "Open the picker to add allowed tenants."
|
||||||
|
picker_hint_with_count = "{{count}} tenants selected."
|
||||||
|
|
||||||
[ui.dev.clients.general.id_token_claims]
|
[ui.dev.clients.general.id_token_claims]
|
||||||
title = "Custom Claims"
|
title = "Custom Claims"
|
||||||
@@ -1652,7 +1677,7 @@ pkce = "PKCE"
|
|||||||
headless_login = "Headless Login"
|
headless_login = "Headless Login"
|
||||||
title = "Security Settings"
|
title = "Security Settings"
|
||||||
headless_login_enable = "Headless Login (Custom Login UI)"
|
headless_login_enable = "Headless Login (Custom Login UI)"
|
||||||
headless_login_enable_help = "Enable this when the RP uses its own login UI and the RP backend proves the client with signed keys instead of the Baron SSO login page."
|
headless_login_enable_help = "Enable this when the RP uses its own login UI instead of the Baron SSO login page and the RP backend validates the client with a signing key."
|
||||||
|
|
||||||
[ui.dev.clients.general.public_key]
|
[ui.dev.clients.general.public_key]
|
||||||
auth_method = "Token Endpoint Auth Method"
|
auth_method = "Token Endpoint Auth Method"
|
||||||
@@ -1683,6 +1708,12 @@ cache_status = "Status"
|
|||||||
cache_uri = "JWKS URI"
|
cache_uri = "JWKS URI"
|
||||||
revoke_cache = "Revoke Cache"
|
revoke_cache = "Revoke Cache"
|
||||||
|
|
||||||
|
[ui.dev.clients.general.public_key.validation]
|
||||||
|
missing_jwks_uri = "Enter a JWKS URI."
|
||||||
|
invalid_jwks_uri = "JWKS URI format is invalid."
|
||||||
|
unsupported_parsed_algorithms = "The JWKS contains unsupported algorithms: {{details}}"
|
||||||
|
missing_parsed_algorithms = "The JWKS contains keys without an `alg` declaration: {{details}}"
|
||||||
|
|
||||||
[ui.dev.clients.relationships]
|
[ui.dev.clients.relationships]
|
||||||
title = "Client Relationships"
|
title = "Client Relationships"
|
||||||
add_title = "Add Relationship"
|
add_title = "Add Relationship"
|
||||||
|
|||||||
@@ -321,12 +321,14 @@ admin_desc = "사용자들의 개발자 권한 신청 내역을 관리합니다.
|
|||||||
approved = "승인되었습니다."
|
approved = "승인되었습니다."
|
||||||
cancelled = "승인이 취소되었습니다."
|
cancelled = "승인이 취소되었습니다."
|
||||||
empty = "신청 내역이 없습니다."
|
empty = "신청 내역이 없습니다."
|
||||||
list.approved_count = "총 {{count}}명의 사용자가 승인되었습니다."
|
|
||||||
need_cancel_notes = "승인 취소 사유를 입력해주세요."
|
need_cancel_notes = "승인 취소 사유를 입력해주세요."
|
||||||
need_notes = "반려 사유를 입력해주세요."
|
need_notes = "반려 사유를 입력해주세요."
|
||||||
rejected = "반려되었습니다."
|
rejected = "반려되었습니다."
|
||||||
user_desc = "내 신청 내역을 확인하고 새로운 권한을 신청할 수 있습니다."
|
user_desc = "내 신청 내역을 확인하고 새로운 권한을 신청할 수 있습니다."
|
||||||
|
|
||||||
|
[msg.dev.request.list]
|
||||||
|
approved_count = "총 {{count}}명의 사용자가 승인되었습니다."
|
||||||
|
|
||||||
[msg.dev.request.modal]
|
[msg.dev.request.modal]
|
||||||
desc = "신청 사유를 입력해 주세요. 관리자 확인 후 승인됩니다."
|
desc = "신청 사유를 입력해 주세요. 관리자 확인 후 승인됩니다."
|
||||||
tenant_required = "개발자 권한 신청을 진행해 주세요."
|
tenant_required = "개발자 권한 신청을 진행해 주세요."
|
||||||
@@ -573,10 +575,8 @@ admin_notes_placeholder = "예: 테스트 환경 확인 후 권한 부여"
|
|||||||
empty = "부여된 권한이 없습니다."
|
empty = "부여된 권한이 없습니다."
|
||||||
forbidden = "개발자 권한 직접 부여는 super admin만 사용할 수 있습니다."
|
forbidden = "개발자 권한 직접 부여는 super admin만 사용할 수 있습니다."
|
||||||
forbidden_desc = "이 화면은 super admin만 사용할 수 있습니다."
|
forbidden_desc = "이 화면은 super admin만 사용할 수 있습니다."
|
||||||
form.description = "사용자를 선택하면 현재 소속 테넌트, 이메일, 전화번호를 확인한 뒤 개발자 권한을 즉시 부여합니다."
|
|
||||||
selected_info_description = "선택된 사용자의 소속, 이메일, 전화번호를 확인합니다."
|
selected_info_description = "선택된 사용자의 소속, 이메일, 전화번호를 확인합니다."
|
||||||
user_section_description = "검색어를 입력해 사용자를 선택합니다. 선택 전에는 다음 단계 정보가 비어 있습니다."
|
user_section_description = "검색어를 입력해 사용자를 선택합니다. 선택 전에는 다음 단계 정보가 비어 있습니다."
|
||||||
list.description = "현재 부여된 개발자 권한 목록입니다."
|
|
||||||
load_error = "개발자 권한 목록을 불러오지 못했습니다."
|
load_error = "개발자 권한 목록을 불러오지 못했습니다."
|
||||||
reason = "부여 사유"
|
reason = "부여 사유"
|
||||||
revoke = "회수"
|
revoke = "회수"
|
||||||
@@ -588,6 +588,13 @@ tenant_required = "선택한 사용자의 테넌트 정보를 확인할 수 없
|
|||||||
tenant_missing = "선택한 사용자의 테넌트 정보를 확인할 수 없습니다."
|
tenant_missing = "선택한 사용자의 테넌트 정보를 확인할 수 없습니다."
|
||||||
user_required = "부여할 사용자를 선택해주세요."
|
user_required = "부여할 사용자를 선택해주세요."
|
||||||
phone_missing = "등록된 전화번호가 없습니다."
|
phone_missing = "등록된 전화번호가 없습니다."
|
||||||
|
pages_hint = "전체를 선택하면 개요, 연동 앱 추가, 감사로그가 모두 포함됩니다."
|
||||||
|
|
||||||
|
[msg.dev.grants.form]
|
||||||
|
description = "사용자를 선택하면 현재 소속 테넌트, 이메일, 전화번호를 확인한 뒤 개발자 권한을 즉시 부여합니다."
|
||||||
|
|
||||||
|
[msg.dev.grants.list]
|
||||||
|
description = "현재 부여된 개발자 권한 목록입니다."
|
||||||
|
|
||||||
[msg.dev.dashboard.notice]
|
[msg.dev.dashboard.notice]
|
||||||
consent_audit = "Consent 회수는 감사 로그와 연계"
|
consent_audit = "Consent 회수는 감사 로그와 연계"
|
||||||
@@ -1351,10 +1358,8 @@ admin_notes = "부여 사유"
|
|||||||
all_tenants = "전체 테넌트"
|
all_tenants = "전체 테넌트"
|
||||||
approved = "승인됨"
|
approved = "승인됨"
|
||||||
date = "부여일"
|
date = "부여일"
|
||||||
form.title = "직접 부여"
|
|
||||||
grant = "직접 부여"
|
grant = "직접 부여"
|
||||||
input_section = "입력"
|
input_section = "입력"
|
||||||
list.title = "부여된 권한"
|
|
||||||
pages = "권한 페이지"
|
pages = "권한 페이지"
|
||||||
read_only = "읽기 전용"
|
read_only = "읽기 전용"
|
||||||
reason = "부여 사유"
|
reason = "부여 사유"
|
||||||
@@ -1369,6 +1374,12 @@ user_section = "사용자 선택"
|
|||||||
user = "사용자"
|
user = "사용자"
|
||||||
user_search_placeholder = "이름 또는 이메일 검색..."
|
user_search_placeholder = "이름 또는 이메일 검색..."
|
||||||
|
|
||||||
|
[ui.dev.grants.form]
|
||||||
|
title = "직접 부여"
|
||||||
|
|
||||||
|
[ui.dev.grants.list]
|
||||||
|
title = "부여된 권한"
|
||||||
|
|
||||||
[ui.dev.request.modal]
|
[ui.dev.request.modal]
|
||||||
email = "이메일"
|
email = "이메일"
|
||||||
name = "성함"
|
name = "성함"
|
||||||
@@ -1380,6 +1391,12 @@ reason_placeholder = "예: 자체 서비스 연동 및 테스트용 OIDC 클라
|
|||||||
role = "역할"
|
role = "역할"
|
||||||
title = "개발자 등록 신청"
|
title = "개발자 등록 신청"
|
||||||
|
|
||||||
|
[ui.dev.access_pages]
|
||||||
|
all = "전체"
|
||||||
|
overview = "개요"
|
||||||
|
client_create = "연동 앱 추가"
|
||||||
|
audit = "감사로그"
|
||||||
|
|
||||||
[ui.dev.request.status]
|
[ui.dev.request.status]
|
||||||
approved = "승인됨"
|
approved = "승인됨"
|
||||||
cancelled = "승인 취소됨"
|
cancelled = "승인 취소됨"
|
||||||
@@ -1596,6 +1613,8 @@ name_placeholder = "e.g. profile"
|
|||||||
title = "스코프"
|
title = "스코프"
|
||||||
offline_access_title = "Refresh token 사용 시 offline_access scope가 필요합니다."
|
offline_access_title = "Refresh token 사용 시 offline_access scope가 필요합니다."
|
||||||
offline_access_toggle = "상세 안내 보기"
|
offline_access_toggle = "상세 안내 보기"
|
||||||
|
picker_title = "추가할 scope 선택"
|
||||||
|
picker_help = "지원 scope와 Custom Claim key를 선택해 scope 목록에 추가합니다."
|
||||||
|
|
||||||
[ui.dev.clients.general.scopes.table]
|
[ui.dev.clients.general.scopes.table]
|
||||||
description = "설명"
|
description = "설명"
|
||||||
@@ -1616,6 +1635,12 @@ empty = "검색 결과가 없습니다."
|
|||||||
hint = "제한을 켜면 tenant 스코프가 자동으로 포함되며, 허용 테넌트를 하나 이상 선택해야 합니다."
|
hint = "제한을 켜면 tenant 스코프가 자동으로 포함되며, 허용 테넌트를 하나 이상 선택해야 합니다."
|
||||||
autocomplete_hint = "테넌트 이름을 입력하면 자동 완성 후보가 나타납니다. 클릭하면 허용 목록에 추가됩니다."
|
autocomplete_hint = "테넌트 이름을 입력하면 자동 완성 후보가 나타납니다. 클릭하면 허용 목록에 추가됩니다."
|
||||||
validation_required = "테넌트 접근 제한을 사용할 경우 허용 테넌트를 하나 이상 선택해야 합니다."
|
validation_required = "테넌트 접근 제한을 사용할 경우 허용 테넌트를 하나 이상 선택해야 합니다."
|
||||||
|
picker_title = "테넌트 선택"
|
||||||
|
picker_label = "허용 테넌트 추가"
|
||||||
|
open_picker = "테넌트 선택기 열기"
|
||||||
|
picker_description = "orgfront 조직도에서 허용할 테넌트를 선택하면 목록에 추가됩니다."
|
||||||
|
picker_hint = "선택기를 열어 허용 테넌트를 추가하세요."
|
||||||
|
picker_hint_with_count = "현재 {{count}}개가 선택되어 있습니다."
|
||||||
|
|
||||||
[ui.dev.clients.general.id_token_claims]
|
[ui.dev.clients.general.id_token_claims]
|
||||||
title = "커스텀 클레임"
|
title = "커스텀 클레임"
|
||||||
@@ -1682,6 +1707,12 @@ cache_status = "상태"
|
|||||||
cache_uri = "JWKS URI"
|
cache_uri = "JWKS URI"
|
||||||
revoke_cache = "캐시 삭제"
|
revoke_cache = "캐시 삭제"
|
||||||
|
|
||||||
|
[ui.dev.clients.general.public_key.validation]
|
||||||
|
missing_jwks_uri = "JWKS URI를 입력해야 합니다."
|
||||||
|
invalid_jwks_uri = "JWKS URI 형식이 올바르지 않습니다."
|
||||||
|
unsupported_parsed_algorithms = "JWKS에 지원하지 않는 알고리즘이 있습니다: {{details}}"
|
||||||
|
missing_parsed_algorithms = "JWKS에 알고리즘(`alg`)이 선언되지 않은 키가 있습니다: {{details}}"
|
||||||
|
|
||||||
[ui.dev.clients.relationships]
|
[ui.dev.clients.relationships]
|
||||||
title = "클라이언트 관계"
|
title = "클라이언트 관계"
|
||||||
add_title = "관계 추가"
|
add_title = "관계 추가"
|
||||||
|
|||||||
@@ -335,16 +335,19 @@ admin_desc = ""
|
|||||||
approved = ""
|
approved = ""
|
||||||
cancelled = ""
|
cancelled = ""
|
||||||
empty = ""
|
empty = ""
|
||||||
list.approved_count = ""
|
|
||||||
need_cancel_notes = ""
|
need_cancel_notes = ""
|
||||||
need_notes = ""
|
need_notes = ""
|
||||||
rejected = ""
|
rejected = ""
|
||||||
user_desc = ""
|
user_desc = ""
|
||||||
|
|
||||||
|
[msg.dev.request.list]
|
||||||
|
approved_count = ""
|
||||||
|
|
||||||
[msg.dev.request.modal]
|
[msg.dev.request.modal]
|
||||||
desc = ""
|
desc = ""
|
||||||
tenant_required = ""
|
tenant_required = ""
|
||||||
tenant_required_detail = ""
|
tenant_required_detail = ""
|
||||||
|
pages_hint = ""
|
||||||
|
|
||||||
[msg.dev.request.status]
|
[msg.dev.request.status]
|
||||||
approved = ""
|
approved = ""
|
||||||
@@ -610,14 +613,13 @@ admin_notes_placeholder = ""
|
|||||||
empty = ""
|
empty = ""
|
||||||
forbidden = ""
|
forbidden = ""
|
||||||
forbidden_desc = ""
|
forbidden_desc = ""
|
||||||
form.description = ""
|
|
||||||
selected_info_description = ""
|
selected_info_description = ""
|
||||||
user_section_description = ""
|
user_section_description = ""
|
||||||
list.description = ""
|
|
||||||
load_error = ""
|
load_error = ""
|
||||||
reason = ""
|
reason = ""
|
||||||
revoke = ""
|
revoke = ""
|
||||||
revoke_success = ""
|
revoke_success = ""
|
||||||
|
pages_hint = ""
|
||||||
search_empty = ""
|
search_empty = ""
|
||||||
search_loading = ""
|
search_loading = ""
|
||||||
selected_user = ""
|
selected_user = ""
|
||||||
@@ -627,6 +629,12 @@ user_required = ""
|
|||||||
phone_missing = ""
|
phone_missing = ""
|
||||||
required = ""
|
required = ""
|
||||||
|
|
||||||
|
[msg.dev.grants.form]
|
||||||
|
description = ""
|
||||||
|
|
||||||
|
[msg.dev.grants.list]
|
||||||
|
description = ""
|
||||||
|
|
||||||
[msg.dev.dashboard.notice]
|
[msg.dev.dashboard.notice]
|
||||||
consent_audit = ""
|
consent_audit = ""
|
||||||
dev_scope = ""
|
dev_scope = ""
|
||||||
@@ -1403,10 +1411,8 @@ admin_notes = ""
|
|||||||
all_tenants = ""
|
all_tenants = ""
|
||||||
approved = ""
|
approved = ""
|
||||||
date = ""
|
date = ""
|
||||||
form.title = ""
|
|
||||||
grant = ""
|
grant = ""
|
||||||
input_section = ""
|
input_section = ""
|
||||||
list.title = ""
|
|
||||||
read_only = ""
|
read_only = ""
|
||||||
reason = ""
|
reason = ""
|
||||||
reason_placeholder = ""
|
reason_placeholder = ""
|
||||||
@@ -1420,6 +1426,12 @@ user_section = ""
|
|||||||
user = ""
|
user = ""
|
||||||
user_search_placeholder = ""
|
user_search_placeholder = ""
|
||||||
|
|
||||||
|
[ui.dev.grants.form]
|
||||||
|
title = ""
|
||||||
|
|
||||||
|
[ui.dev.grants.list]
|
||||||
|
title = ""
|
||||||
|
|
||||||
[ui.dev.request.modal]
|
[ui.dev.request.modal]
|
||||||
email = ""
|
email = ""
|
||||||
name = ""
|
name = ""
|
||||||
@@ -1430,6 +1442,12 @@ reason_placeholder = ""
|
|||||||
role = ""
|
role = ""
|
||||||
title = ""
|
title = ""
|
||||||
|
|
||||||
|
[ui.dev.access_pages]
|
||||||
|
all = ""
|
||||||
|
overview = ""
|
||||||
|
client_create = ""
|
||||||
|
audit = ""
|
||||||
|
|
||||||
[ui.dev.request.status]
|
[ui.dev.request.status]
|
||||||
approved = ""
|
approved = ""
|
||||||
cancelled = ""
|
cancelled = ""
|
||||||
@@ -1645,6 +1663,8 @@ name_placeholder = ""
|
|||||||
title = ""
|
title = ""
|
||||||
offline_access_title = ""
|
offline_access_title = ""
|
||||||
offline_access_toggle = ""
|
offline_access_toggle = ""
|
||||||
|
picker_title = ""
|
||||||
|
picker_help = ""
|
||||||
|
|
||||||
[ui.dev.clients.general.scopes.table]
|
[ui.dev.clients.general.scopes.table]
|
||||||
description = ""
|
description = ""
|
||||||
@@ -1665,6 +1685,12 @@ empty = ""
|
|||||||
hint = ""
|
hint = ""
|
||||||
autocomplete_hint = ""
|
autocomplete_hint = ""
|
||||||
validation_required = ""
|
validation_required = ""
|
||||||
|
picker_title = ""
|
||||||
|
picker_label = ""
|
||||||
|
open_picker = ""
|
||||||
|
picker_description = ""
|
||||||
|
picker_hint = ""
|
||||||
|
picker_hint_with_count = ""
|
||||||
|
|
||||||
[ui.dev.clients.general.id_token_claims]
|
[ui.dev.clients.general.id_token_claims]
|
||||||
title = ""
|
title = ""
|
||||||
@@ -1730,6 +1756,12 @@ cache_status = ""
|
|||||||
cache_uri = ""
|
cache_uri = ""
|
||||||
revoke_cache = ""
|
revoke_cache = ""
|
||||||
|
|
||||||
|
[ui.dev.clients.general.public_key.validation]
|
||||||
|
missing_jwks_uri = ""
|
||||||
|
invalid_jwks_uri = ""
|
||||||
|
unsupported_parsed_algorithms = ""
|
||||||
|
missing_parsed_algorithms = ""
|
||||||
|
|
||||||
[ui.dev.clients.relationships]
|
[ui.dev.clients.relationships]
|
||||||
title = ""
|
title = ""
|
||||||
add_title = ""
|
add_title = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user