Files
huly-platform/plugins/setting-assets/lang/ko.json
T
Don KendallandGitHub 5a3d673e84 feat(account): revocable API tokens managed from account settings (#10624)
* feat: API token management in workspace settings

Add UI and backend support for creating, listing, and revoking
API tokens scoped to workspaces. Includes owner-level workspace
token visibility, OpenAPI documentation, Mongo/Postgres persistence,
and i18n translations.

Signed-off-by: Don Kendall <kendall@donkendall.com>

* feat: enforce API token revocation at transactor level

Embed apiTokenId in JWT extra field and add a per-token revocation
cache (60s TTL) in the transactor REST handler. Revoked tokens are
now rejected within ~60 seconds instead of remaining valid until
JWT expiry.

Adds checkApiTokenRevoked account service method for the transactor
to query individual token revocation status.

Signed-off-by: Don Kendall <kendall@donkendall.com>

* feat: implement Phase 1 API token scopes (read/write/delete)

Add coarse-grained scope enforcement for API tokens. Tokens can now
be created with scopes ['read:*'], ['read:*','write:*'], or
['read:*','write:*','delete:*']. Existing tokens without scopes
retain full access (backward compatible).

- DB: v26 migration adds scopes TEXT[] column to api_tokens
- Types: add scopes field to ApiToken and ApiTokenInfo
- Operations: createApiToken accepts/validates/persists scopes,
  embeds in JWT via extra.scopes
- Enforcement: withSession checks scopes against method; tx handler
  additionally requires delete:* for TxRemoveDoc
- Client: createApiToken signature accepts optional scopes param
- UI: scope preset dropdown in create popup (default: Read Only),
  permissions column in token list with i18n labels
- Also fixes 3 pre-existing TS2322/TS2345 errors in operations.ts

Signed-off-by: Don Kendall <kendall@donkendall.com>

* test: add unit tests for API token scope enforcement

- scopes.test.ts: 8 tests for hasScope() and getRequiredScope() logic
- apiTokenScopes.test.ts: 7 tests for createApiToken scope validation
  (valid scopes, multiple scopes, no scopes backward compat, invalid
  format rejection, empty array rejection, domain-scope rejection)
  and listApiTokens scopes inclusion
- Export hasScope/getRequiredScope from rpc.ts for testability

Signed-off-by: Don Kendall <kendall@donkendall.com>

* fix: address review feedback — role restriction, locale parity, formatting

- Restrict API token creation/revocation to AccountRole.User or higher
  (guests cannot use API tokens), per reviewer suggestion
- Add 5 missing translation keys (ApiTokenPermissions, ApiTokenScopePreset,
  ApiTokenScopeReadOnly, ApiTokenScopeReadWrite, ApiTokenScopeFullAccess)
  to all non-en locale files to fix locale parity CI test
- Fix prettier formatting in apiTokenScopes.test.ts
- Rename local `extra` to `tokenExtra` in createApiToken to avoid
  shadowing the decoded token's `extra` field

Signed-off-by: Don Kendall <kendall@donkendall.com>

* fix: address aonnikov architectural review feedback

- rpc.ts: use system service token for checkApiTokenRevoked so the
  revocation check is not coupled to the user's potentially-revoked
  bearer token; systemAccountUuid + service:'server' ensures account
  service always accepts the call
- ApiDocsSection.svelte: derive transactor base URL from
  login.metadata.LoginEndpoint (set on auth) instead of
  window.location.origin, which is not necessarily the transactor host
- ApiTokenCreatePopup.svelte: replace manual translate() calls and
  themeStore language watch with DropdownLabelsIntl + DropdownIntlItem[],
  which handle i18n automatically; error state is now IntlString
- General.svelte: remove legacy GenerateApiToken button, handler, and
  ApiTokenPopup import in favour of the new ApiTokens settings panel

Signed-off-by: Don Kendall <kendall@donkendall.com>

* fix: formatting in ApiTokenPopup, apiTokenScopes test, and operations

Signed-off-by: Don Kendall <kendall@donkendall.com>

* fix: apply rushx fmt to pass CI formatting check

Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* fix: restore (s as any) cast in server_http.ts removed by ESLint autofix

Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* refactor(token): centralize API token revocation/expiry in verifyToken

Address @aonnikov's review: the bespoke checkApiTokenRevoked RPC and the
ad-hoc revocation cache in the transactor are replaced by a reusable
verifyToken in server-token that checks signature, expiry, and (for
revokable API tokens) revocation via a pluggable checker.

- server-token: add verifyToken + isTokenExpired + setApiTokenRevocationChecker
  (the 'method to verify' metadata the plugin needs, without depending on the
  account client). Revocation cache (60s TTL) now lives here, reusable by any
  service (transactor, blob access, etc.).
- account: the account is now authoritative — wrap() rejects revoked/expired
  API tokens, so any account method (selectWorkspace/getWorkspaceInfo/...)
  naturally 401s. Removed the redundant checkApiTokenRevoked method.
- account-client: drop checkApiTokenRevoked.
- transactor: withSession uses verifyToken; the registered checker reuses the
  existing getLoginInfoByToken instead of a dedicated boolean RPC. Scopes are
  parsed once and threaded through (no re-decode in the tx handler).
- tests: verifyToken/isTokenExpired unit coverage.

Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* fix(setting): derive REST API base from account-provided transactor endpoint

Address @aonnikov: the REST API host must come from the transactor endpoint
returned by the account service (the login endpoint, a ws(s):// URL), not be
constructed from window.location. Convert ws->http and append /api/v1, matching
the existing ServerManagerGeneral pattern.

Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* i18n(setting): translate API token strings across all locales

Address @ArtyomSavchenko: the new API token UI strings were left in English
in non-en locales. Provide translations for ru/de/es/fr/it/pt/pt-br/zh/ja/cs/tr.
The en/ru locale-parity test passes (the prior failure was an en/ru key
mismatch, resolved by the develop merge).

Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* style: wrap long lines to satisfy prettier (account utils import, ApiDocsSection)

Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* fix(api-token): drop unenforceable scopes, harden the token lifecycle

The scopes were only ever consulted in the transactor's REST handler, so
they promised a boundary the platform did not keep:

- the WebSocket transport decodes the token and never looks at scopes, so
  a read-only token could open a socket and issue any transaction;
- even on the REST path, delete:* only matched a top-level TxRemoveDoc and
  was bypassed by nesting the removal in a TxApplyIf;
- nothing stopped a scoped token from calling createApiToken and minting
  an unscoped one.

Narrowing a token's rights has to happen in the pipeline, where it covers
every transport, and that is a larger design than this feature. Until then
a token carries its account's rights and says so, rather than displaying a
restriction that does not hold. Scopes are removed end to end.

What is kept is made to work:

- API tokens can no longer create, list or revoke API tokens. Otherwise a
  leaked token renews itself and revokes the tokens meant to stop it.
- Revocation fails closed. The account is the only authority on it, so an
  unreachable account now rejects the token instead of admitting a revoked
  one to whoever can keep the account busy. Verdicts stay trusted for the
  cache TTL so brief outages do not cut off healthy tokens.
- The revocation cache is bounded and re-checks negative verdicts.
- Revoking your own token no longer requires a role in its workspace, so
  leaving a workspace cannot strand a credential you can never revoke.
- The per-account limit counts only usable tokens; revoked and expired
  ones are kept for the audit trail and used to lock out anyone rotating.
- Rejected REST tokens are logged with a reason, since expired, revoked
  and unverifiable are one opaque 401 from outside.

The unused listWorkspaceApiTokens/revokeWorkspaceApiToken pair is removed;
it had no caller and no test.

Tests cover the role restriction, the API-token guard, ownership on
revoke, the limit accounting and fail-closed revocation. Removing any of
those checks fails them.

Claude-Session: https://claude.ai/code/session_01ANdoXbdn5k2hZy734EwKe7
Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* fix(setting): correct the API token settings page

- Moves the page from workspace settings to account settings. Tokens
  belong to the account: the page already lists them across every
  workspace, and creating one only needs the User role the account
  service checks, not Owner as the category required.
- Surfaces failures. A failed revoke was logged to the console and the
  row re-rendered unchanged; loading workspaces could reject unhandled
  and leave an empty dropdown with no explanation.
- Outside a secure context there is no clipboard API, so the OK button
  did nothing and the dialog had no way out but Cancel. It now closes,
  leaving the token selectable.
- Replaces hardcoded English labels, adds aria-expanded on the docs
  disclosure and labels on the copy targets.
- Fills in the Korean and Polish translations, which were the only two
  locales missing these keys, and drops the API access strings orphaned
  when this PR replaced the old Generate API token button.

Claude-Session: https://claude.ai/code/session_01ANdoXbdn5k2hZy734EwKe7
Signed-off-by: Don Kendall <dkendall@ledoweb.com>

* chore: drop docs/openapi.yaml from the API token PR

Unrelated to this feature and wrong for this repo: it documents a
/_tokens minting service and a tools/mint-token CLI that do not exist
here, uses reverse-proxy prefixes from a self-hosted deployment rather
than the transactor's /api/v1 routes, and states that revocation is a
future enhancement, which is what this PR implements. Nothing references
it. REST API docs belong in their own change, generated against the
routes that exist.

Claude-Session: https://claude.ai/code/session_01ANdoXbdn5k2hZy734EwKe7
Signed-off-by: Don Kendall <dkendall@ledoweb.com>

---------

Signed-off-by: Don Kendall <kendall@donkendall.com>
Signed-off-by: Don Kendall <dkendall@ledoweb.com>
2026-08-04 13:10:48 +07:00

287 lines
17 KiB
JSON

{
"string": {
"Setting": "설정",
"Spaces": "스페이스",
"Integrations": "연동",
"Support": "고객 지원",
"Privacy": "개인정보 보호",
"Terms": "이용약관",
"AccountSettings": "계정 설정",
"Categories": "카테고리",
"Delete": "삭제",
"ChangePassword": "비밀번호 변경",
"Disconnect": "연결 해제",
"DisconnectAll": "모두 연결 해제",
"Saving": "저장 중...",
"Saved": "저장됨",
"Add": "추가",
"AddNew": "{type} 추가",
"Proceed": "계속",
"NewEmail": "새 이메일",
"SendConfirmation": "인증 코드 전송",
"CodeSent": "코드를 전송했습니다. 아래 입력란에 입력하세요.",
"SendAgain": "다시 보내기",
"SendAgainIn": "재전송 가능 시간",
"Value": "값",
"Signout": "로그아웃",
"Settings": "설정",
"SelectWorkspace": "워크스페이스 선택",
"InviteWorkspace": "워크스페이스에 초대",
"DeleteStatus": "상태 삭제",
"DeleteStatusConfirm": "이 상태를 삭제하시겠습니까?",
"Reconnect": "재연결",
"IntegrationDisabled": " 연동이 비활성화되었습니다",
"IntegrationDisabledSetting": "연동이 비활성화되었습니다",
"IntegrationDisabledDescr": "연동 비활성화됨",
"IntegrationWith": "다음과 연동: ",
"ClassSetting": "클래스 설정",
"ClassSettingHint": "종류, 유형 또는 품질에 따라 다른 것들과 공통의 속성을 가진 사물의 집합 또는 카테고리입니다.",
"ClassProperties": "클래스 속성",
"Classes": "클래스",
"Attributes": "속성",
"DeleteAttribute": "속성 삭제",
"DeleteAttributeConfirm": "이 속성을 삭제하시겠습니까?",
"DeleteAttributeExistConfirm": "이 속성을 삭제하시겠습니까? 데이터가 손실됩니다.",
"DeleteMixin": "믹스인 삭제",
"DeleteMixinConfirm": "이 Mixin을 삭제하시겠습니까?",
"DeleteMixinExistConfirm": "이 Mixin을 삭제하시겠습니까? 데이터를 사용할 수 없게 됩니다.",
"Attribute": "속성",
"Custom": "사용자 지정",
"Type": "유형",
"WithTime": "시간 포함",
"DateMode": "날짜 모드",
"CreatingAttribute": "속성 생성 중",
"EditAttribute": "속성 편집",
"CreateEnum": "열거형 생성",
"EditEnum": "열거형 편집",
"Enums": "열거형",
"EnumsSettingHint": "종류, 유형 또는 품질에 따라 다른 것들과 공통의 속성을 가진 사물의 집합 또는 카테고리입니다.",
"EnumTitle": "열거형 제목",
"EnumsCount": "{count, plural, =1 {옵션 1개} other {옵션 #개}}",
"ProjectTypesCount": "{count, plural, =0 {프로젝트 유형 없음} =1 {프로젝트 유형 1개} other {프로젝트 유형 #개}}",
"Options": "옵션",
"EnterOptionTitle": "옵션 제목 입력",
"NewEnumDialogClose": "이 대화 상자를 닫으시겠습니까?",
"NewEnumDialogCloseNote": "모든 변경 사항이 손실됩니다",
"NewValue": "새 값",
"Leave": "워크스페이스 나가기",
"LeaveDescr": "워크스페이스에서 나가시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"Members": "멤버",
"WorkspaceSettings": "워크스페이스 설정",
"Select": "선택",
"AddOwner": "소유자 추가",
"ReadonlyGuest": "읽기 전용",
"Guest": "게스트",
"User": "사용자",
"Maintainer": "유지관리자",
"Owner": "소유자",
"OwnerFirstName": "소유자 이름",
"OwnerLastName": "소유자 성",
"Role": "역할",
"FailedToSave": "비밀번호 업데이트에 실패했습니다",
"ImportEnum": "열거형 값 가져오기",
"ImportEnumCopy": "클립보드에서 열거형 값 복사",
"CreateMixin": "믹스인 생성",
"OldNames": "이전 값",
"NewClassName": "새 클래스 이름을 입력하거나 이전 값에서 선택...",
"ShowAttribute": "속성 표시",
"HideAttribute": "속성 숨기기",
"Visibility": "표시 설정",
"Hidden": "숨김",
"Configure": "설정",
"InviteSettings": "초대 설정",
"RoleCapabilitySettings": "역할 권한",
"DefaultInviteRoleForJoin": "초대 링크로 참여 시 부여되는 기본 역할:",
"InviteLinkGeneratorRoles": "초대 링크를 생성할 수 있는 사용자 역할 선택:",
"DefaultValue": "기본값",
"SelectAValue": "값 선택",
"DateOnly": "날짜만",
"OnlyTime": "시간만",
"DateAndTime": "날짜와 시간",
"Configuration": "구성",
"ConfigurationEnabled": "활성화됨",
"ConfigurationDisabled": "비활성화됨",
"ConfigDisable": "비활성화",
"ConfigEnable": "활성화",
"ConfigBeta": "베타 버전",
"Properties": "속성",
"TaskTypes": "작업 유형",
"Automations": "자동화",
"Collections": "컬렉션",
"ClassColon": "클래스:",
"SpaceTypes": "스페이스 유형",
"NewSpaceType": "새 스페이스 유형",
"SpaceTypeTitle": "스페이스 유형 제목",
"General": "일반",
"Description": "설명",
"CountSpaces": "{count, plural, =0 {스페이스 없음} =1 {스페이스 1개} other {스페이스 #개}}",
"Roles": "역할",
"RoleName": "역할 이름",
"Permissions": "권한",
"Assignees": "담당자",
"DeleteRole": "역할 삭제",
"DeleteRoleConfirmation": "이 역할을 삭제하시겠습니까? 이 역할을 가진 모든 사용자가 권한을 잃게 됩니다.",
"DeleteWorkspace": "워크스페이스 삭제",
"DeleteWorkspaceConfirm": "이 워크스페이스를 삭제하시겠습니까? 본인과 다른 모든 멤버가 이 워크스페이스에 접근할 수 없게 되며, 워크스페이스의 모든 정보가 손실됩니다. 이 작업은 되돌릴 수 없습니다. 계속하시겠습니까?",
"DeleteSpaceType": "스페이스 유형 삭제",
"DeleteSpaceTypeConfirm": "이 스페이스 유형을 삭제하시겠습니까?",
"WorkspaceName": "워크스페이스 이름",
"Workspace": "워크스페이스",
"OwnerOrMaintainerRequired": "워크스페이스 소유자 또는 유지관리자여야 합니다",
"LastOwnerLeaveTitle": "워크스페이스를 나갈 수 없습니다",
"LastOwnerLeaveMessage": "이 워크스페이스의 유일한 소유자입니다. 나가려면 먼저 다른 멤버에게 소유자 권한을 부여하세요. 더 이상 이 워크스페이스가 필요하지 않다면 삭제를 고려해 보세요.",
"Backup": "백업",
"BackupLast": "마지막 백업",
"BackupTotalSnapshots": "총 스냅샷",
"BackupTotalFiles": "파일",
"BackupSize": "백업 크기",
"BackupLinkInfo": "wget이나 curl 같은 도구로 재귀적으로 다운로드할 수 있는 백업 디렉터리의 URL입니다.",
"BackupBearerTokenInfo": "백업에 접근하려면 Bearer 토큰이 필요합니다.",
"BackupSnapshots": "백업 스냅샷",
"BackupFileDownload": "파일 다운로드",
"BackupFiles": "백업 파일",
"BackupNoBackup": "현재 사용 가능한 백업이 없습니다.",
"BackupDownloadAll": "전체 백업 다운로드",
"BackupPreparingDownload": "백업 준비 중…",
"BackupDownloadAllInfo": "모든 백업 파일을 컴퓨터에 보관할 수 있는 단일 .zip 아카이브로 다운로드합니다.",
"BackupCopyScript": "다운로드 스크립트 복사",
"BackupCopyToken": "토큰 복사",
"BackupScriptInfo": "curl로 모든 백업 파일을 다운로드하는 셸 스크립트입니다. 저장한 후 터미널에서 실행하세요. 백업 토큰을 입력하라는 메시지가 표시되므로 스크립트에 비밀 정보가 저장되지 않습니다.",
"BackupRestoreGuide": "백업 및 복원 가이드",
"BackupRestoreGuideInfo": "이 백업을 다운로드하여 다른 Huly 인스턴스로 복원하는 단계별 안내입니다.",
"NonBackupedBlobs": "백업되지 않은 Blob",
"Calendar": "캘린더",
"StartOfTheWeek": "주 시작일",
"SystemSetupString": "시스템 설정 ({day})",
"DefaultString": "기본값 ({day})",
"AddAttribute": "속성 추가",
"WorkspaceNamePattern": "이름은 40자 이하여야 하며, 비워둘 수 없고 특수 문자(<, >, /)를 포함할 수 없습니다",
"Mailboxes": "메일함",
"CreateMailbox": "메일함 생성",
"CreateMailboxPlaceholder": "my-cool-name",
"MailboxNoDomains": "이메일 도메인이 구성되지 않았습니다",
"MailboxLimitReached": "메일함 한도에 도달했습니다",
"MailboxErrorInvalidName": "메일함 이름이 유효하지 않습니다",
"MailboxErrorDomainNotFound": "도메인을 찾을 수 없습니다",
"MailboxErrorNameRulesViolated": "메일함 이름은 {minLen}~{maxLen}자여야 합니다",
"MailboxErrorMailboxExists": "이미 사용 중인 메일함 이름입니다",
"MailboxErrorMailboxCountLimit": "계정의 메일함 개수 한도에 도달했습니다",
"DeleteMailbox": "메일함 삭제",
"MailboxDeleteConfirmation": "이 메일함을 삭제하시겠습니까?",
"DisablePermissions": "역할 기반 접근 제어 비활성화",
"EnablePermissions": "역할 기반 접근 제어 활성화",
"DisablePermissionsConfirmation": "역할 기반 접근 제어를 비활성화하시겠습니까? 모든 역할과 권한이 비활성화됩니다.",
"EnablePermissionsConfirmation": "역할 기반 접근 제어를 활성화하시겠습니까? 모든 역할과 권한이 활성화됩니다.",
"BetaWarning": "베타로 표시된 모듈은 실험용이며 완전히 작동하지 않을 수 있습니다. 현재로서는 중요한 작업에 베타 기능을 사용하는 것을 권장하지 않습니다.",
"IntegrationFailed": "연동 생성에 실패했습니다",
"IntegrationError": "다시 시도하거나, 문제가 지속되면 지원팀에 문의하세요",
"EmailIsUsed": "이미 다른 계정에서 사용 중인 이메일 주소입니다",
"Customize": "사용자 정의",
"GuestAccess": "익명 게스트",
"GuestAccessDescription": "익명 사용자가 워크스페이스를 읽기 전용 모드로 방문할 수 있도록 허용",
"GuestSignUpDescription": "익명 사용자가 제한된 편집 권한의 게스트로 워크스페이스에 참여할 수 있도록 허용",
"GuestChannelsDescription": "참여 후 게스트가 메시지를 작성할 수 있는 채널",
"GuestChannelsArrayLabel": "채널 선택",
"GuestSelectSpaces": "스페이스 선택",
"GuestAutoJoinAvailableSpaces": "자동 참여 스페이스",
"GuestAutoJoinAvailableSpacesHint": "각 애플리케이션 카드에는 \"자동 참여 스페이스\" 행이 있습니다. 워크스페이스 게스트가 활성화될 때 추가될 위치를 선택하세요. 변경 사항은 즉시 적용됩니다.",
"GuestAnonymousVisibleSpaces": "익명 사용자에게 표시되는 스페이스",
"GuestAnonymousVisibleSpacesHint": "각 애플리케이션 카드에는 자체 행이 있습니다. 읽기 전용 익명 계정이 멤버로 추가되는 스페이스를 선택하면 계정이 없는 방문자도 해당 스페이스를 열 수 있습니다. 변경 사항은 즉시 적용됩니다.",
"ManageIdentities": "ID 관리",
"Release": "해제",
"ReleaseSocialId": "소셜 ID 해제",
"ReleaseSocialIdConfirm": "이 소셜 ID({socialId})를 해제하시겠습니까? 계정에서 제거되며 더 이상 로그인에 사용할 수 없습니다. 또한 관련된 모든 연동도 제거됩니다.",
"ReleasePrimarySocialId": "기본 소셜 ID 해제",
"ReleasePrimarySocialIdConfirm": "현재 기본 소셜 ID를 해제하려면 페이지를 새로고침해야 합니다. 계속하시겠습니까?",
"Login": "로그인",
"Primary": "기본",
"MyIntegrations": "내 연동",
"AllIntegrations": "전체",
"ConnectedIntegrations": "연동됨",
"AvailableIntegrations": "사용 가능",
"Connect": "연결",
"Integrate": "연동",
"FailedToLoadIntegrations": "연동을 불러오는 데 실패했습니다",
"FailedToDisconnect": "연동 연결 해제에 실패했습니다",
"ServiceIsUnavailable": "서비스를 사용할 수 없습니다",
"Integrated": "연동됨",
"Connected": "연결됨",
"Disconnected": "연결 해제됨",
"Available": "사용 가능",
"NotConnectedIntegration": "{account} 계정이 워크스페이스와 연동되어 있지 않습니다",
"IntegrationIsUnstable": "연동 서비스에 문제가 발생했습니다. 일부 기능이 제대로 작동하지 않을 수 있습니다.",
"MinValue": "최솟값",
"MaxValue": "최댓값",
"IntegerOnly": "정수만",
"AccessControl": "접근 제어",
"DangerZone": "위험 구역",
"IdentifierExists": "이미 존재하는 식별자입니다",
"Reset": "재설정",
"Restricted": "제한됨",
"RestrictedAttributeWarning": "이 속성의 변경을 제한하시겠습니까? 이 속성에 대한 권한이 생성되며 작업은 되돌릴 수 없습니다.",
"PasswordAgingRule": "비밀번호 만료 규칙",
"PasswordAgingRuleDescription": "사용자가 비밀번호를 변경해야 하는 일수",
"OfficeSettings": "오피스 설정",
"OfficeDefaultSettings": "회의실 기본 설정",
"DefaultStartWithTranscription": "새 오피스 회의실에서 자동 기록 활성화",
"DefaultStartWithRecording": "새 오피스 회의실에서 녹화 활성화",
"GuestPermissionsSettings": "게스트",
"GuestPermissionsApplicationPermissions": "애플리케이션 권한",
"GuestPermissionsApplicationPermissionsHint": "게스트가 사용할 수 있는 애플리케이션을 선택한 다음, 아래에서 각 애플리케이션의 권한을 조정하세요.",
"GuestPermissionsTabGuest": "게스트",
"GuestPermissionsTabAnonymousGuest": "익명 게스트",
"GuestPermissionsAnonymousApplicationHint": "익명(읽기 전용) 게스트의 애플리케이션 접근 권한입니다. 표시되는 애플리케이션은 배포 구성에 따라 달라질 수 있습니다.",
"ImportDocumentPermission": "문서 가져오기",
"ImportDocumentDescription": "사용자에게 워크스페이스로 문서를 가져올 권한을 부여",
"SelectUsers": "사용자 선택",
"ShowInTitle": "제목에 표시",
"SpaceMembersOnly": "스페이스 멤버 전용",
"Security": "보안",
"TwoFactorAuth": "2단계 인증",
"TwoFactorAuthDescription": "2단계 인증은 계정에 추가적인 보안 계층을 더해 줍니다",
"EnableTwoFactorAuth": "2단계 인증 활성화",
"DisableTwoFactorAuth": "2단계 인증 비활성화",
"TwoFactorAuthEnabled": "2단계 인증이 활성화됨",
"TwoFactorAuthDisabled": "2단계 인증이 비활성화됨",
"ShowQRCode": "QR 코드 표시",
"EnterVerificationCode": "인증 코드 입력",
"OverrideAttribute": "속성 재정의",
"Required": "필수",
"ApiTokenStatusActive": "활성",
"ApiTokenStatusExpiring": "만료 예정",
"ApiTokenStatusRevoked": "취소됨",
"ApiTokenStatusExpired": "만료됨",
"ApiTokenExpiry7Days": "7일",
"ApiTokenExpiry30Days": "30일",
"ApiTokenExpiry90Days": "90일",
"ApiTokenExpiry180Days": "180일",
"ApiTokenExpiry365Days": "365일",
"ApiTokenLoadError": "API 토큰을 불러오지 못했습니다",
"ApiTokenCreateError": "토큰 생성에 실패했습니다. 다시 시도해 주세요.",
"ApiTokens": "API 토큰",
"CreateApiToken": "토큰 생성",
"ApiTokenName": "토큰 이름",
"ApiTokenExpiry": "만료",
"ApiTokenCreated": "토큰이 생성됨",
"ApiTokenRevoke": "토큰 취소",
"ApiTokenRevokeConfirm": "이 토큰을 취소하시겠습니까? 더 이상 API 접근에 사용할 수 없습니다.",
"ApiTokenCopyWarning": "지금 이 토큰을 복사하세요. 다시 확인할 수 없습니다.",
"ApiTokenNoTokens": "아직 API 토큰이 없습니다",
"ApiTokenWorkspace": "워크스페이스",
"Created": "생성일",
"Expires": "만료일",
"TokenStatus": "상태",
"ApiUsageTitle": "REST API 사용",
"ApiUsageDescription": "내장 REST API에서 API 토큰을 사용하여 워크스페이스 데이터를 조회하고 수정할 수 있습니다. Authorization 헤더에 Bearer 토큰으로 전달하세요.",
"ApiEndpointPing": "상태 확인",
"ApiEndpointFindAll": "클래스별 문서 조회",
"ApiEndpointFindAllPost": "필터로 조회 (JSON 본문)",
"ApiEndpointTx": "문서 생성 또는 수정",
"ApiEndpointLoadModel": "데이터 모델 불러오기",
"ApiEndpointAccount": "계정 정보 가져오기",
"ApiBaseUrl": "기본 URL",
"ApiWorkspaceId": "워크스페이스 ID(UUID)는 토큰에 포함되어 있습니다. URL에서 :workspaceId로 전달하세요.",
"ApiTokenRevokeError": "토큰 취소에 실패했습니다. 다시 시도해 주세요."
}
}