From 2a9b044992774d3680dd2dfae142e0526b28c076 Mon Sep 17 00:00:00 2001 From: kyy Date: Mon, 20 Apr 2026 10:43:57 +0900 Subject: [PATCH] =?UTF-8?q?RP=20=EC=88=98=EC=A0=95=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=95=88=EB=82=B4=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/clients/ClientDetailsPage.tsx | 17 ++++++++++++++++- .../src/features/clients/ClientGeneralPage.tsx | 13 ++++++++++++- devfront/src/locales/en.toml | 9 +++++++++ devfront/src/locales/ko.toml | 9 +++++++++ devfront/src/locales/template.toml | 9 +++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/devfront/src/features/clients/ClientDetailsPage.tsx b/devfront/src/features/clients/ClientDetailsPage.tsx index 7d6825fb..82e43d43 100644 --- a/devfront/src/features/clients/ClientDetailsPage.tsx +++ b/devfront/src/features/clients/ClientDetailsPage.tsx @@ -84,9 +84,24 @@ function ClientDetailsPage() { ); }, onError: (err) => { + const axiosError = err as AxiosError<{ error?: string }>; + if (axiosError.response?.status === 403) { + toast( + t( + "msg.dev.clients.details.save_forbidden", + "이 RP 설정을 수정할 권한이 없습니다.\n관리자에게 RP 일반 설정 또는 RP 관리자 관계 부여를 요청해 주세요.", + ), + "error", + ); + return; + } + toast( t("msg.dev.clients.details.save_error", "저장 실패: {{error}}", { - error: (err as Error).message, + error: + axiosError.response?.data?.error ?? + (err as Error).message ?? + t("msg.common.unknown_error", "unknown error"), }), "error", ); diff --git a/devfront/src/features/clients/ClientGeneralPage.tsx b/devfront/src/features/clients/ClientGeneralPage.tsx index dedff139..a19ee5ed 100644 --- a/devfront/src/features/clients/ClientGeneralPage.tsx +++ b/devfront/src/features/clients/ClientGeneralPage.tsx @@ -527,8 +527,19 @@ function ClientGeneralPage() { alert(t("msg.dev.clients.general.saved", "설정이 저장되었습니다.")); }, onError: (err) => { + const axiosError = err as AxiosError<{ error?: string }>; + if (axiosError.response?.status === 403) { + alert( + t( + "msg.dev.clients.general.save_forbidden", + "이 RP 설정을 수정할 권한이 없습니다.\n관리자에게 RP 일반 설정 또는 RP 관리자 관계 부여를 요청해 주세요.", + ), + ); + return; + } + const errorMessage = - (err as AxiosError<{ error?: string }>).response?.data?.error ?? + axiosError.response?.data?.error ?? (err as Error)?.message ?? t("msg.common.unknown_error", "unknown error"); alert( diff --git a/devfront/src/locales/en.toml b/devfront/src/locales/en.toml index a321c0d3..bf5ff541 100644 --- a/devfront/src/locales/en.toml +++ b/devfront/src/locales/en.toml @@ -332,6 +332,8 @@ showing = "Showing {{shown}} of {{total}} apps" deleted = "App deleted." delete_error = "Failed to delete: {{error}}" delete_confirm = "Are you sure you want to delete this app? This action cannot be undone." +empty = "No RPs are available." +empty_detail = "RPs will appear here when a relationship is assigned to your account." [msg.dev.clients.consents] empty = "No consents found." @@ -352,6 +354,7 @@ redirect_saved = "Redirect URIs saved." rotate_confirm = "Rotate Confirm" rotate_error = "Rotate Error" save_error = "Save Error" +save_forbidden = "You do not have permission to edit this RP. Ask an administrator to grant RP General Settings or RP Admin relationship." secret_rotated = "Secret Rotated" secret_unavailable = "SECRET_NOT_AVAILABLE" subtitle = "Manage OIDC credentials and endpoints." @@ -368,6 +371,7 @@ load_error = "Error loading client: {{error}}" loading = "Loading client..." saved = "Saved" save_error = "Failed to save: {{error}}" +save_forbidden = "You do not have permission to edit this RP. Ask an administrator to grant RP General Settings or RP Admin relationship." status_changed = "Status changed to {{status}}." [msg.dev.clients.relationships] @@ -1310,6 +1314,7 @@ untitled = "Untitled" [ui.dev.clients.badge] admin_session = "Admin Session" +dev_session = "DevFront Session" tenant_selected = "Tenant Selected" [ui.dev.clients.filter] @@ -1510,6 +1515,10 @@ description = "Revoke consent grants for this RP." label = "Relationship View" description = "View direct relations assigned to this RP." +[ui.dev.clients.relationships.option.audit_viewer] +label = "Audit Log View" +description = "View DevFront audit logs for this RP." + [ui.dev.clients.relationships.option.status_operator] label = "Status Change" description = "Change the active or inactive state of the RP." diff --git a/devfront/src/locales/ko.toml b/devfront/src/locales/ko.toml index 7f5903f5..61fcc171 100644 --- a/devfront/src/locales/ko.toml +++ b/devfront/src/locales/ko.toml @@ -329,6 +329,8 @@ subtitle = "현재 테넌트/앱 범위의 DevFront 작업 이력을 조회합 deleted = "앱이 삭제되었습니다." delete_confirm = "정말로 이 앱을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다." delete_error = "삭제 실패: {{error}}" +empty = "조회 가능한 RP가 없습니다." +empty_detail = "RP 관계가 부여되면 이 목록에 해당 RP가 표시됩니다." load_error = "앱 정보를 불러오지 못했습니다: {{error}}" loading = "앱 정보를 불러오는 중..." showing = "전체 {{total}}개 중 {{shown}}개를 표시하는 중입니다." @@ -352,6 +354,7 @@ redirect_saved = "Redirect URIs가 저장되었습니다." rotate_confirm = "경고: Client Secret을 재발급하면 기존 시크릿은 즉시 무효화됩니다.\n연동된 애플리케이션이 중단될 수 있습니다. 계속하시겠습니까?" rotate_error = "재발급 실패: {{error}}" save_error = "저장 실패: {{error}}" +save_forbidden = "이 RP 설정을 수정할 권한이 없습니다.\n관리자에게 RP 일반 설정 또는 RP 관리자 관계 부여를 요청해 주세요." secret_rotated = "Client Secret이 재발급되었습니다." secret_unavailable = "SECRET_NOT_AVAILABLE" subtitle = "OIDC 자격 증명과 엔드포인트를 관리합니다." @@ -367,6 +370,7 @@ note = "엔드포인트는 읽기 전용으로 유지하고, 비밀키 재발행 load_error = "클라이언트 정보를 불러오지 못했습니다: {{error}}" loading = "클라이언트 정보를 불러오는 중..." save_error = "저장 실패: {{error}}" +save_forbidden = "이 RP 설정을 수정할 권한이 없습니다.\n관리자에게 RP 일반 설정 또는 RP 관리자 관계 부여를 요청해 주세요." saved = "설정이 저장되었습니다." status_changed = "상태가 {{status}}로 변경되었습니다." @@ -1310,6 +1314,7 @@ untitled = "Untitled" [ui.dev.clients.badge] admin_session = "관리자 세션" +dev_session = "DevFront 세션" tenant_selected = "테넌트: 선택됨" [ui.dev.clients.filter] @@ -1509,6 +1514,10 @@ description = "이 RP의 consent를 회수합니다." label = "관계 조회" description = "이 RP에 부여된 direct relation을 조회합니다." +[ui.dev.clients.relationships.option.audit_viewer] +label = "감사 로그 조회" +description = "이 RP의 DevFront 감사 로그를 조회합니다." + [ui.dev.clients.relationships.option.status_operator] label = "상태 변경" description = "RP 활성/비활성 상태를 변경합니다." diff --git a/devfront/src/locales/template.toml b/devfront/src/locales/template.toml index a7f4d16c..94c2c4fe 100644 --- a/devfront/src/locales/template.toml +++ b/devfront/src/locales/template.toml @@ -332,6 +332,8 @@ showing = "" deleted = "" delete_error = "" delete_confirm = "" +empty = "" +empty_detail = "" [msg.dev.clients.consents] empty = "" @@ -352,6 +354,7 @@ redirect_saved = "" rotate_confirm = "" rotate_error = "" save_error = "" +save_forbidden = "" secret_rotated = "" secret_unavailable = "" subtitle = "" @@ -368,6 +371,7 @@ load_error = "" loading = "" saved = "" save_error = "" +save_forbidden = "" status_changed = "" [msg.dev.clients.relationships] @@ -1311,6 +1315,7 @@ untitled = "" [ui.dev.clients.badge] admin_session = "" +dev_session = "" tenant_selected = "" [ui.dev.clients.filter] @@ -1509,6 +1514,10 @@ description = "" label = "" description = "" +[ui.dev.clients.relationships.option.audit_viewer] +label = "" +description = "" + [ui.dev.clients.relationships.option.status_operator] label = "" description = ""