- 스트림:
- Internet Engineering Task Force (IETF)
- RFC:
- 9553
- 분류:
- 표준 트랙 (Standards Track)
- 발행:
- ISSN:
- 2070-1721
초록
이 명세는 주소록 또는 디렉터리 애플리케이션에서 데이터 저장과 교환에 사용할 수 있는 연락처 카드 정보의 데이터 모델과 JavaScript Object Notation(JSON) 표현을 정의한다. 이는 vCard 데이터 형식의 대안을 목표로 하며, 모호하지 않고 확장 가능하며 처리하기 쉬운 형식을 지향한다. JSON 기반 jCard 형식과 달리 vCard 데이터 모델을 직접 매핑한 것이 아니며, 적절한 경우 의미 체계를 확장한다. 두 개의 추가 명세는 새로운 vCard 요소와 JSContact 및 vCard 간 변환 방법을 정의한다.
이 메모의 상태
이 문서는 인터넷 표준 트랙(Internet Standards Track) 문서이다.
이 문서는 Internet Engineering Task Force(IETF)의 산출물이다. IETF 커뮤니티의 합의를 나타내며, 공개 검토를 거쳐 Internet Engineering Steering Group(IESG)의 출판 승인을 받았다. 인터넷 표준에 대한 추가 정보는 RFC 7841의 Section 2에서 확인할 수 있다.
이 문서의 현재 상태, 정오표(errata), 피드백 제공 방법에 관한 정보는 https://www.rfc-editor.org/info/rfc9553에서 확인할 수 있다.
저작권 고지
Copyright (c) 2024 IETF Trust 및 이 문서의 저자로 식별된 사람들. 모든 권리 보유.
이 문서는 발행일 현재 유효한 BCP 78 및 IETF Trust의 IETF 문서에 관한 법적 조항(https://trustee.ietf.org/license-info)의 적용을 받는다. 이 문서들은 이 문서와 관련한 권리와 제한을 설명하므로 주의 깊게 검토해야 한다. 이 문서에서 추출한 Code Components에는 Trust Legal Provisions의 Section 4.e에 설명된 Revised BSD License 문구를 포함해야 하며, Revised BSD License에 설명된 대로 어떠한 보증도 없이 제공된다.
1. 소개
이 문서는 일반적으로 주소록 또는 디렉터리 애플리케이션과 서비스에서 사용하는 연락처 카드 데이터의 데이터 모델을 정의한다. vCard 데이터 형식 [RFC6350]의 대안을 목표로 한다.
이 데이터 모델의 주요 설계 고려사항은 다음과 같다.
- 데이터 모델과 속성 집합은 vCard 데이터 형식 [RFC6350] 및 확장 [RFC6473] [RFC6474] [RFC6715] [RFC6869] [RFC8605]에서 정의된 모델과 대부분 호환되어야 한다. 적절한 경우 이 명세는 새로운 속성 또는 값 형식을 추가해야 한다. 기존의 모든 vCard 정의에 JSContact의 동등한 요소가 반드시 필요한 것은 아니며, 특히 해당 vCard 정의가 폐기되었거나 부적절하다고 간주되는 경우 그러하다. 데이터 형식 간 변환은 의미를 완전히 보존할 필요가 없다.
- 카드 데이터 표현의 복잡성을 줄이기 위해 카드 데이터의 속성은 단순한 키-값 쌍으로 기술되어야 한다.
- 데이터 모델은 모든 모호성을 피하고 구현 중 실수하기 어렵도록 해야 한다.
- 새로운 프로퍼티와 컴포넌트 같은 확장은 이 문서를 반드시 갱신해야 하는 상황으로 이어져서는 안 된다(MUST NOT).
이 데이터 모델의 표현은 JSON 데이터 교환 형식 [RFC8259]의 엄격한 하위 집합인 Internet JSON(I-JSON) 형식 [RFC7493]으로 정의된다. JSON을 사용하는 것은 주로 실용적인 선택이다. 널리 사용되기 때문에 JSContact를 채택하기 쉬우며, 프로덕션 환경에서 사용할 수 있는 JSON 구현이 이미 존재하므로 파서 관련 상호운용성 문제의 한 범주 전체를 제거할 수 있다.
1.1. 동기와 vCard, jCard, xCard와의 관계
vCard 데이터 형식 [RFC6350]은 주소록 서비스 제공자와 벤더 간 연락처 데이터를 교환하기 위한 형식이다. 그러나 이 형식은 여러 차례 명세가 개정되었고, 폐기된 version 3 [RFC2426]의 일부만 널리 사용되고 있다. 그 결과 제품과 서비스는 vCard로 직렬화해 노출하는 정보보다 더 풍부한 내부 연락처 데이터 모델을 사용한다. 또한 서비스 제공자는 API에서 독자적인 JSON 연락처 데이터 표현을 사용하는 경우가 많다.
JSContact는 이러한 독자 형식의 대안으로 표준 JSON 기반 연락처 데이터 모델과 표현을 제공한다.
이 문서 작성 당시 소셜 미디어 연락처, 성별 대명사 등 vCard에 빠져 있는 여러 기능이 저자들에게 지적되었다. 이는 vCard가 진화하는 형식으로 인식되지 않고 있으며, 그 결과 약 10년 동안 갱신되지 않았음을 보여준다. JSContact는 이러한 미충족 요구를 다루고, 두 형식 모두에서 교환할 수 있도록 새로운 vCard 프로퍼티와 파라미터를 정의한다.
두 개의 추가 문서가 JSContact와 vCard의 관계를 정의한다. [RFC9554]는 새로운 vCard 프로퍼티와 파라미터를 정의하고, [RFC9555]는 JSContact 데이터를 vCard로 또는 vCard에서 JSContact로 변환하는 방법을 정의한다.
xCard [RFC6351]와 jCard [RFC7095] 명세는 각각 XML과 JSON으로 vCard 데이터를 표현하는 대체 표현을 정의한다. 둘 다 기저 데이터 모델을 변경하지 않는 것을 명시적으로 목표로 한다. 따라서 이 문서의 맥락에서는 vCard와 동일한 것으로 간주한다.
1.2. 표기 규칙
이 문서의 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, “OPTIONAL”이라는 키워드는 여기에서처럼 모두 대문자로 나타날 때에만 BCP 14 [RFC2119] [RFC8174]에 기술된 의미로 해석한다.
이 문서의 ABNF 정의는 [RFC5234]의 표기법을 사용한다. 이 문서에서 정의하지 않은 ABNF 규칙은 [RFC5234](예: CRLF, WSP, DQUOTE, VCHAR, ALPHA, DIGIT의 ABNF) 또는 [RFC6350]에서 정의된다.
1.3. 데이터 타입 표기
이 절에서는 JSContact의 데이터 타입을 정의하는 데 사용되는 표기법과 용어를 소개한다.
JSContact의 기반 형식은 JSON이므로 데이터 타입 또한 JSON 값을 기반으로 한다. “object”와 “array”, 그리고 네 가지 원시 타입(“strings”, “numbers”, “booleans”, “null”)은 [RFC8259]의 Section 1에 설명된 의미로 해석한다. 모든 JSContact 데이터는 I-JSON [RFC7493]에 주어진 제약에 따라 유효해야 한다(MUST). 별도로 명시하지 않는 한 JSON 객체의 모든 멤버 이름과 모든 문자열 값은 대소문자를 구분한다. JSON 객체의 맥락에서 “key”라는 용어는 [RFC8259] Section 1의 “member name”과 동의어이다.
1.3.1. 객체와 프로퍼티
JSContact는 주소나 이름 같은 연락처 정보를 위한 데이터 타입을 정의한다. 이러한 정보는 일반적으로 여러 관련 요소로 구성된다. 예를 들어 개인의 이름(given name)과 성(surname)은 함께 하나의 이름을 이룬다. 이러한 관련 요소는 JSContact 객체로 구성된다. JSContact 객체는 다음을 갖는 JSON 객체이다.
- IANA “JSContact Types” 레지스트리(Section 3.6)에 등록된 고유한 타입 이름.
- 이름과 허용되는 값 타입이 명시된 하나 이상의 객체 멤버. 이러한 멤버를 “properties”라고 한다.
- JSContact 객체의 타입 이름과 일치하는 문자열 값을 갖는
@type이라는 프로퍼티 하나. 일반적으로 이 프로퍼티는 Section 1.3.4에 설명된 대로 명시적으로 설정할 필요가 없다.
다음 절들은 JSContact 객체 타입을 정의하는 방법을 명시한다. 이어 1.7절과 1.8절에서 프로퍼티 이름에 대한 정확한 요구사항을 정의한다.
다음 단락은 JSContact 객체가 어떻게 정의되는지 예시한다. “Foo”와 “baz”라는 이름은 예시용일 뿐이며 예시 밖에서는 어떠한 의미도 없다.
Foo 객체에는 다음과 같은 속성이 있다.
- @type: String.
- 객체의 JSContact 타입. 설정하는 경우 값은 “Foo”여야 한다(MUST).
- baz: Number (mandatory).
- 연락처의 baz 수준. 값은 0보다 크고 10보다 작은 정수여야 한다(MUST).
위 단락은 다음을 보여준다.
- “@type”과 “baz”라는 두 프로퍼티를 갖는 “Foo”라는 이름의 JSContact 객체 타입을 정의한다.
@type프로퍼티는 Section 1.3.4의 규칙을 따른다. 따라서 Foo 객체 타입이 어떻게 사용되는지에 따라 달라지므로 mandatory 또는 optional로 정의되지 않는다.baz프로퍼티 값은 Number 타입의 정의에 따라 유효해야 한다(MUST).- 이 프로퍼티에는 “mandatory”라는 속성이 하나 있으며, Foo 객체 타입의 값이 유효하려면 해당 프로퍼티가 반드시 존재해야 함(MUST)을 명시한다.
baz프로퍼티의 자유 텍스트 설명은 값의 의미와 추가 제한을 설명한다.
1.3.2. 타입 시그니처
이 문서의 모든 JSON 값과 JSContact 정의에는 타입 시그니처가 주어진다. 다음 규칙을 사용한다.
- String:
- JSON 문자열 타입.
- Number:
- JSON 숫자 타입.
- Boolean:
- JSON 불리언 타입.
- A[B]:
- 모든 키가 A 타입이고 모든 값이 B 타입인 JSON 객체.
- A[]:
- A 타입 값으로 이루어진 JSON 배열.
- A|B:
- 값이 A 타입 또는 B 타입 중 하나임을 나타낸다.
- *:
- 타입이 정의되지 않음(값은 어떤 타입이든 될 수 있으나, 허용되는 값은 해당 값이 사용되는 문맥에 따라 제한될 수 있다.)
Section 1.4는 부호 있는/없는 정수와 날짜를 포함하는 공통 데이터 타입을 정의한다.
1.3.3. 프로퍼티 속성
객체 프로퍼티에는 타입 시그니처와 함께 정의되는 속성 집합이 있을 수 있다. 그 의미는 다음과 같다.
- mandatory:
- 이 객체의 인스턴스가 유효하려면 해당 속성이 반드시 설정되어야 한다(MUST).
- optional:
- 이 객체의 인스턴스가 유효하기 위해 해당 속성을 설정할 수도 있지만 필수는 아니다.
- default:
- 뒤에 JSON 값이 온다. 해당 속성이 생략된 경우 이 값을 사용한다.
- defaultType:
-
뒤에 JSContact 객체 타입의 이름이 온다. JSContact 객체 타입의 속성 값에서
@type속성이 생략된 경우, 해당 값은 여기서 지정한 타입인 것으로 간주한다.
1.3.4. @type 프로퍼티
@type: String.
JSON 객체의 JSContact 타입. 해당 JSON 객체가 인스턴스인 JSContact 객체의 타입 이름과 일치해야 한다(MUST).
@type 프로퍼티의 목적은 구현체가 주어진 JSON 객체가 어떤 JSContact 객체 타입을 나타내는지 식별하도록 돕는 것이다. 구현체는 이 프로퍼티를 가진 JSON 객체가 해당 이름의 JSContact 객체 타입 명세를 준수하는지 검증해야 한다(MUST).
많은 경우 @type 프로퍼티 값은 JSContact 데이터에서 객체가 나타나는 위치에 의해 암시된다. A와 B가 모두 JSContact 객체 타입이라고 가정한다.
- 타입 시그니처가 “A”인 프로퍼티의 값으로 설정된 객체는
@type프로퍼티를 설정할 수 있다(MAY).@type을 설정하지 않으면 프로퍼티 정의에 의해 그 값은 A로 암시된다. - 타입 시그니처가 “A|B (defaultType: A)”인 프로퍼티의 값으로 설정된 객체가 A의 인스턴스라면
@type을 설정할 수 있다(MAY). B의 인스턴스라면@type을 설정해야 한다(MUST). 반대로defaultType속성이 정의되지 않았다면 A에 대해서도@type을 설정해야 한다(MUST). - JSON 데이터의 최상위 객체처럼(직접 또는 배열 멤버로) 어떤 프로퍼티의 값도 아닌 객체는
@type프로퍼티를 설정해야 한다(MUST).
1.4. 공통 데이터 타입
표준 JSON 데이터 타입 외에도 몇 가지 추가 데이터 타입이 JSContact 객체와 프로퍼티 정의 전반에 공통으로 사용된다.
1.4.1. Id
“Id”가 데이터 타입으로 주어지면, 이는 크기가 최소 1옥텟에서 최대 255옥텟인 String을 의미하며, [RFC4648]의 Section 5에 정의된 “URL and Filename Safe” base64url 알파벳에서 패딩 문자(“=”)를 제외한 문자만 포함해야 한다(MUST). 즉 허용 문자는 ASCII 영숫자(“A-Za-z0-9”), 하이픈(“-“), 밑줄(“_”)이다.
JSContact의 여러 곳에서는 맵 키가 Id 타입이고 맵 값이 모두 같은 객체 타입인 JSON 맵을 사용한다. 이 구조는 순서가 없는 객체 집합을 나타내며, 각 엔트리가 이름(대응하는 맵 키)을 갖는다는 장점이 추가된다. 이를 통해 객체를 더 간결하게 패치할 수 있고, 해당되는 경우 JSContact 객체 내의 다른 객체가 그 객체를 참조할 수 있다. 맵 키는 JSContact 객체의 여러 버전에 걸쳐 보존되어야 한다(MUST).
특정 프로퍼티에 별도로 명시하지 않는 한 Id 값에는 고유성 제약이 없다(물론 하나의 JSON 맵 안에서 같은 키를 가진 두 값을 둘 수 없다는 요구사항은 제외). 예를 들어 두 Card(Section 2) 객체가 각각의 photos 프로퍼티에서 같은 Id를 사용할 수 있다. 또는 같은 Card 안에서 emails와 phones 프로퍼티에 같은 Id가 나타날 수도 있다. 이러한 상황은 객체 사이에 어떠한 의미적 연결도 암시하지 않는다.
1.4.2. Int와 UnsignedInt
“Int”가 데이터 타입으로 주어지면 JSON Number로 표현되는, 부동소수점 double에 안전하게 저장할 수 있는 범위인 -2^53+1 <= value <= 2^53-1의 정수를 의미한다.
“UnsignedInt”가 데이터 타입으로 주어지면 JSON Number로 표현되는 0 <= value <= 2^53-1 범위의 정수를 의미한다.
1.4.3. PatchObject
PatchObject는 “String[*]” 타입이며 JSON 객체에 대한 순서 없는 패치 집합을 나타낸다. 각 키는 JSON Pointer 형식 [RFC6901]의 하위 집합으로 표현된 경로이다. 경로에는 암시적인 선행 “/”가 있으므로 JSON Pointer 평가 알고리즘을 적용하기 전에 각 키 앞에 “/”를 붙인다.
PatchObject 안의 패치는 다음 조건을 모두 만족할 때에만 유효하다.
- 포인터는 배열 내부를 참조할 수 있다(MAY). 그러나 포인터의 마지막 참조 토큰이 배열 인덱스라면 패치 값은 null이어서는 안 된다(MUST NOT). 포인터는 참조 토큰 어디에서도 “-“를 배열 인덱스로 사용해서는 안 된다(MUST NOT). 즉 배열에 삽입/삭제해서는 안 되지만(MUST NOT), 기존 멤버의 내용은 교체할 수 있다(MAY). 멤버를 추가하거나 제거하려면 전체 배열 값을 교체해야 한다.
- 마지막 참조 토큰(즉 마지막 슬래시 뒤의 값)을 제외한 모든 참조 토큰은 패치 대상 객체에 이미 값으로 존재해야 한다(MUST). 마지막 참조 토큰이 배열 인덱스라면 해당 인덱스의 멤버가 참조된 배열에 이미 존재해야 한다(MUST).
- PatchObject에는 한 포인터가 다른 포인터의 접두사인 두 패치가 있어서는 안 된다(MUST NOT). 예: “addresses/1/city”와 “addresses”.
- 패치 값은 설정되는 프로퍼티에 대해 유효해야 한다(MUST)(올바른 타입이며 기타 적용 가능한 제한을 준수해야 함). 값이 null이면 해당 프로퍼티는 optional이어야 한다(MUST).
각 포인터와 연관된 값은 패치를 적용하는 방법을 결정한다.
- null이면 패치 대상 객체에서 해당 프로퍼티를 제거한다. 부모에 키가 없으면 아무 작업도 하지 않는다(no-op).
- null이 아니면 주어진 값을 해당 프로퍼티 값으로 설정한다(기존 값 교체 또는 새 값 추가일 수 있음).
PatchObject는 자체 @type(Section 1.3.4) 프로퍼티를 정의하지 않는다. 대신 패치 안의 @type 프로퍼티는 다른 패치된 프로퍼티 값과 동일하게 처리해야 한다(MUST).
패치 중 하나라도 유효하지 않으면 구현체는 PatchObject 전체를 거부해야 한다(MUST). 구현체는 부분 패치를 적용해서는 안 된다(MUST NOT).
1.4.4. Resource
Resource 데이터 타입은 URI [RFC3986]로 식별되는, Card가 나타내는 엔터티와 연관된 리소스를 정의한다. 이 문서 뒤에서 여러 프로퍼티 정의가 프로퍼티별 값 타입의 기반으로 Resource 타입을 참조한다. Resource 타입은 이들 모두에 공통인 프로퍼티를 정의한다. Resource를 사용하는 프로퍼티 정의는 값 타입에 추가 프로퍼티를 정의할 수 있다(MAY).
Resource 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 값은 “Resource”여서는 안 되며(MUST NOT), 대신 구체적인 리소스 타입 이름이어야 한다(MUST)(Section 2.6 참조).
kind: String (optional).
리소스의 종류. 허용 값은 Resource 타입을 사용하는 해당 프로퍼티 정의에서 정의한다. 일부 프로퍼티 정의는 이 프로퍼티를 optional에서 mandatory로 변경할 수 있다.
uri: String (mandatory).
리소스 값. [RFC3986]의 Section 3에 정의된 _URI_여야 한다(MUST).
mediaType: String (optional).
uri 프로퍼티 값으로 식별된 리소스의 미디어 타입 [RFC2046].
contexts: String[Boolean] (optional).
이 리소스를 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
다른 리소스와 비교한 이 리소스의 선호도. Section 1.5.3도 참조.
label: String (optional).
값에 대한 사용자 정의 레이블. Section 1.5.2도 참조.
1.4.5. UTCDateTime
UTCDateTime 타입은 [RFC3339]의 “date-time” 형식인 String이며, 모든 문자는 대문자여야 하고(MUST) 시간 오프셋은 문자 “Z”여야 한다(MUST)는 추가 제약이 있다. 소수 초 값은 0이 아닌 경우에만 포함해야 하며(MUST NOT otherwise), 각 날짜-시간에 하나의 표현만 존재하도록 후행 0을 가져서는 안 된다(MUST NOT).
예를 들어 “2010-10-10T10:10:10.003Z”는 적합하지만 “2010-10-10T10:10:10.000Z”는 유효하지 않다. 올바른 인코딩은 “2010-10-10T10:10:10Z”이다.
1.5. 공통 프로퍼티
이 문서의 대부분 프로퍼티는 하나의 JSContact 객체 타입에만 해당하며 해당 객체 타입과 함께 정의된다. 이 절의 프로퍼티들은 여러 데이터 타입에 공통이므로 반복을 피하기 위해 여기에서 정의한다. 이 프로퍼티들은 해당 객체 타입에 허용된다고 명시적으로 언급된 경우에만 JSContact 객체에 설정해야 한다(MUST).
1.5.1. contexts
contexts: String[Boolean].
연락처 정보를 사용할 컨텍스트. 예를 들어 어떤 사람에게 업무용과 개인용 전화번호가 각각 있을 수 있으며 phones(Section 2.3.3) 프로퍼티의 각 전화번호에 원하는 컨텍스트를 설정할 수 있다.
이 절은 공통 컨텍스트를 정의한다. 이 프로퍼티를 사용하는 프로퍼티나 데이터 타입에서 추가 컨텍스트를 정의할 수 있다. 공통 컨텍스트의 열거형(Section 1.7.5) 값은 다음과 같다.
- private: 개인 컨텍스트에서 사용할 수 있는 연락처 정보.
- work: 업무 컨텍스트에서 사용할 수 있는 연락처 정보.
1.5.2. label
label: String.
연락처 데이터와 연관된 레이블. 이러한 레이블은 전화번호, 이메일 주소, 기타 리소스에 설정할 수 있다. 일반적으로 그래픽 사용자 인터페이스에서 관련 연락처 데이터와 함께 표시한다. 작은 그래픽 인터페이스와 화면에서 적절히 표시하려면 간결한 레이블이 가장 좋다.
1.5.3. pref
pref: UnsignedInt.
연락처 정보의 선호 순서. 예를 들어 한 사람이 두 개의 이메일 주소를 가지고 있고 그중 하나로 연락받는 것을 선호할 수 있다.
값은 1에서 100 범위여야 한다(MUST). 작은 값일수록 선호도가 높으며 1이 가장 선호된다. 선호도가 설정되지 않으면 해당 연락처 정보는 가장 낮은 선호도로 해석해야 한다(MUST).
선호도는 같은 타입의 연락처 정보끼리의 관계에서만 정의된다. 예를 들어 이메일과 전화번호 내부의 선호 순서는 서로 독립적이다.
1.5.4. phonetic
다음 프로퍼티들은 Card의 language(Section 2.1.5) 프로퍼티 또는 localizations(Section 2.7.1)의 언어 태그가 나타내는 언어에서 값을 어떻게 발음하는지 정의한다. 예를 들어 일본어 이름의 발음을 정의하거나 중국어(표준 중국어/광둥어) 이름 및 주소 컴포넌트를 로마자로 표기하는 데 사용할 수 있다. 프로퍼티는 다음과 같이 정의된다.
phonetic: String.
값의 음성 표현. Card language(Section 2.1.5) 프로퍼티의 script language subtag는 phonetic 프로퍼티와 함께 사용할 때 무시해야 한다(MUST). 이 프로퍼티가 설정되면 이 값과 관련된 phoneticScript 또는 phoneticSystem 중 적어도 하나를 설정해야 한다(MUST).
phoneticScript: String.
관련 phonetic 프로퍼티 값에 사용된 문자(script). [RFC5646]의 Section 2.2.3에 정의된 유효한 script subtag여야 한다(MUST).
phoneticSystem: String.
관련 phonetic 프로퍼티 값에 사용된 음성 체계. 열거형(Section 1.7.5) 값은 다음과 같다.
- ipa: International Phonetic Alphabet [IPA]을 나타낸다.
- jyut: 광둥어 로마자 표기 체계 “Jyutping”을 나타낸다.
- piny: 표준 중국어 로마자 표기 체계 “Hanyu Pinyin”을 나타낸다.
phoneticSystem, phoneticScript, phonetic 프로퍼티 사이의 관계는 타입별로 정의된다. 이 명세는 각각 Name(Section 2.2.1.1)과 Address(Section 2.5.1.1) 객체 타입에서 이 관계를 정의한다.
다음 예시는 name(Section 2.2.1)에 대한 phonetic 프로퍼티를 보여준다.
"name": { "components": \[{ "kind": "given", "value": "John", "phonetic": "/ˈdʒɑːn/" }, { "kind": "surname", "value": "Smith", "phonetic": "/smɪθ/" }\], "phoneticSystem": "ipa"}
Figure 1: 미국식 발음의 “John Smith” 이름에 대한 phonetic 프로퍼티 예
1.6. 국제화
JSContact는 국제적인 연락처와 주소록 데이터에 사용되는 것을 목표로 한다. 특히 이름과 주소 같은 텍스트 값은 매우 다양한 언어와 문화를 포괄할 가능성이 높다. 이 절에서는 자유 형식 텍스트 값과 Uniform Resource Identifier(URI)의 국제화를 설명한다.
1.6.1. 자유 형식 텍스트
자유 형식 텍스트 값을 갖는 프로퍼티는 JSON 문자열로 인코딩할 수 있는 유효한 Unicode 문자 시퀀스를 포함할 수 있다(MAY). 이러한 값은 단방향 좌→우 및 우→좌 텍스트뿐만 아니라 [UBiDi] Section 2에 설명된 Unicode Directional Formatting Characters를 이용한 양방향 텍스트도 포함할 수 있다. 양방향 텍스트를 설정하는 구현체는 각 프로퍼티 값이 Unicode Bidirectional Algorithm의 요구사항을 준수하도록 해야 한다(MUST). 구현체는 인접한 프로퍼티의 텍스트 값이 결합된 하나의 문자열로 처리되거나 표시된다고 가정해서는 안 된다(MUST NOT). 예를 들어 given name 컴포넌트 값과 surname 컴포넌트 값은 함께 렌더링될 수도 있고 그렇지 않을 수도 있다.
1.6.2. URI
여러 프로퍼티는 문자열 값이 [RFC3986]에 정의된 URI일 것을 요구한다. 구현체는 비예약 URI 문자로 표현할 수 없는 URI에 적절한 percent-encoding을 사용해야 한다(MUST). [RFC3987]의 Section 3.1은 Internationalized Resource Identifier를 URI로 변환하는 방법을 정의한다. JSContact는 URI 표시 방식에 관해 권고하지 않지만 WHATWG URL Living Standard의 “Internationalization and special characters”(Section 4.8.3 of [WHATWG-URL])는 웹 브라우저 맥락에서 발견되는 URL에 대한 지침을 제공한다.
1.7. JSContact 검증
이 명세는 검증과 관련해 세 종류의 프로퍼티를 구분한다. 이 절에서 정의하는 IANA 등록 프로퍼티와 알 수 없는 프로퍼티, 그리고 Section 1.8.1에서 정의하는 벤더 전용 프로퍼티이다. JSContact 객체의 프로퍼티 하나라도 유효하지 않으면 해당 JSContact 객체는 유효하지 않다.
이 문서는 각 프로퍼티가 mandatory인지 optional인지 정의한다. JSContact 객체가 유효하려면 mandatory 프로퍼티가 존재해야 한다(MUST). optional 프로퍼티는 존재하지 않아도 된다. mandatory와 optional 프로퍼티의 값 모두 해당 프로퍼티의 데이터 타입과 정의를 준수해야 한다(MUST).
1.7.1. 대소문자 구분
정의에서 명시적으로 달리 규정하지 않는 한 모든 프로퍼티 이름, 객체 타입 이름, 열거형 값은 대소문자를 구분한다. 타입 이름, 프로퍼티 이름 또는 열거형 값이 구현체가 알고 있는 어떤 JSContact 버전에 정의된 값과 대소문자만 다를 경우 구현체는 해당 JSContact 객체를 유효하지 않은 것으로 처리해야 한다(MUST). 이는 Card 객체가 version(Section 2.1.2) 프로퍼티에서 어떤 JSContact 버전을 정의하든 적용된다. Section 1.7.4는 알 수 없는 프로퍼티를 처리하는 방법을 정의한다.
1.7.2. IANA 등록 프로퍼티
IANA 등록 프로퍼티는 Section 3에 설명된 IANA 프로퍼티 레지스트리 규칙에 따라 등록된 프로퍼티이다. 객체 값 타입과 열거형 값을 포함해 이 명세에서 정의된 모든 프로퍼티는 IANA에 등록된다.
구현체가 알 수 없는 프로퍼티(Section 1.7.4)가 아닌 한, 구현체는 JSContact 데이터의 IANA 등록 프로퍼티를 검증해야 한다(MUST). 유효하지 않은 IANA 등록 프로퍼티는 거부해야 한다(MUST). 프로퍼티 이름이 IANA 등록 프로퍼티 이름과 일치하지만 그 값이 Card version(Section 2.1.2) 프로퍼티에 정의된 JSContact 명세 버전에 따른 정의를 위반하면 해당 프로퍼티는 유효하지 않다.
IANA 등록 프로퍼티 이름에는 ASCII 제어 문자(U+0000~U+001F, U+007F), COLON(U+003A), QUOTATION MARK(U+0022)가 포함되어서는 안 된다(MUST NOT). [RFC5234]의 Appendix B.1에 정의된 ALPHA와 DIGIT 규칙에 일치하는 ASCII 영숫자 또는 COMMERCIAL AT(U+0040) 문자만 포함해야 한다(MUST). IANA 등록 프로퍼티 이름은 lower camel case로 표기해야 한다(MUST).
1.7.3. 예약된 프로퍼티
IANA 등록 프로퍼티는 예약될 수 있다(Section 3.3). 구현체는 해당 프로퍼티가 예약된 JSContact 객체에 예약 이름을 가진 프로퍼티를 설정해서는 안 되며(MUST NOT), 레지스트리의 property context가 “not applicable”이면 모든 객체에서 설정해서는 안 된다(MUST NOT). 예약 프로퍼티에는 타입이 없으며 타입 시그니처는 “not applicable”이다. 해당 객체의 맥락에서 예약된 프로퍼티를 포함하는 JSContact 객체는 유효하지 않은 것으로 간주해야 한다(MUST).
이 문서는 아래와 같이 하나의 프로퍼티를 예약한다.
1.7.3.1. extra
extra: not applicable.
예약 프로퍼티 “extra”는 어떠한 JSContact 객체에서도 프로퍼티로 절대 나타나지 않을 것이 보장되는 프로퍼티 이름을 구현자에게 제공한다. 구현체는 알 수 없거나 벤더 전용 프로퍼티를 이 이름의 변수에 매핑하고자 할 수 있지만, 이는 구현에 따라 다르다.
1.7.4. 알 수 없는 프로퍼티
구현체는 자신에게 알려지지 않았지만 IANA 등록 프로퍼티 이름의 구문 제한을 준수하는 프로퍼티 이름을 가진 JSContact 데이터를 접할 수 있다. 구현체는 그러한 이름이 Section 1.7.1에 정의된 대소문자 구분 규칙을 위반하지 않는지 확인해야 한다(MUST). 프로퍼티 이름이 유효하다면 구현체는 그러한 프로퍼티를 유효하지 않은 것으로 취급해서는 안 된다(MUST NOT). 대신 JSContact 객체에 보존해야 한다(MUST).
JSContact 데이터를 생성하거나 갱신하는 구현체는 IANA 등록 프로퍼티 또는 벤더 전용 프로퍼티만 설정해야 한다(MUST). 구현체에 알려지지 않은 프로퍼티를 보존하는 목적은 모든 애플리케이션과 서비스가 동일한 JSContact 확장 집합을 구현하지 않더라도 데이터 손실 없이 상호운용할 수 있도록 하기 위함이다.
1.7.5. 열거형 값
이 문서의 여러 프로퍼티는 허용되는 값을 String 값 목록으로 제한한다. 이 값들은 대소문자를 구분한다. 특정 프로퍼티에 달리 명시하지 않는 한 그러한 프로퍼티의 초기 값 목록은 IANA “JSContact Enum Values” 레지스트리(Section 3.7)에 등록된다. 구현체는 IANA 등록 값 또는 벤더 전용(Section 1.8.2) 값만 설정해야 한다(MUST).
1.8. 벤더 전용 확장
벤더는 실험 또는 단일 서비스나 애플리케이션에만 유용한 연락처 데이터를 저장하기 위해 프로퍼티와 값을 확장할 수 있다. 그러한 확장은 상호운용을 위한 것이 아니다. 반대로 상호운용이 필요하다면 벤더는 Section 3에 정의된 대로 새로운 프로퍼티, 타입, 값을 정의해 IANA에 등록할 것을 강하게 권고한다. Section 1.7.2는 IANA 등록 요소의 명명 규칙을 정의한다.
1.8.1. 벤더 전용 프로퍼티
벤더 전용 프로퍼티 이름은 아래의 “v-extension” ABNF가 생성하는 것처럼 벤더 전용 접두사로 시작하고 그 뒤에 이름이 와야 한다(MUST). 접두사와 이름이 함께 프로퍼티 이름을 이룬다. 벤더 전용 접두사는 해당 프로퍼티를 설정하는 서비스 또는 애플리케이션이 제어하는 도메인 이름이어야 하지만(MUST), Domain Name System [RFC1034] [RFC1035]에서 실제로 해석될 필요는 없다. 접두사 “ietf.org”와 그 하위 도메인 이름은 IETF 명세를 위해 예약된다. 이름에는 TILDE(U+007E)와 SOLIDUS(U+002F) 문자가 포함되어서는 안 된다(MUST NOT). 이 문자들은 해당 프로퍼티에 대한 JSON Pointer [RFC6901]를 인코딩할 때 특별한 이스케이프가 필요하기 때문이다.
벤더 전용 프로퍼티는 어떤 JSContact 객체에도 설정할 수 있다(MAY). 구현체는 그 용도를 알든 모르든 JSContact 데이터의 벤더 전용 프로퍼티를 보존해야 한다(MUST). 위 단락에 설명된 방식으로 해당 벤더 전용 프로퍼티를 제어하는 구현체가 아니라면 프로퍼티 값을 유효하지 않다고 거부해서는 안 된다(MUST NOT).
ABNF 규칙 “v-extension”은 유효한 벤더 전용 프로퍼티 이름을 형식적으로 정의한다. 벤더 접두사는 Internationalized Domain Names(IDN) [RFC9499]보다 더 많은 값을 허용하므로, JSContact 구현체는 도메인 이름에 적용되는 전체 규칙을 구현하지 않고도 단순히 프로퍼티 이름을 검증할 수 있다.
v-extension = v-prefix ":" v-namev-prefix = v-label \*("." v-label)v-label = alnum-int / alnum-int \*(alnum-int / "-") alnum-intalnum-int = ALPHA / DIGIT / NON-ASCII ; see RFC 6350, Section 3.3v-name = 1\*(WSP / "!" / %x23-2e / %x30-7d / NON-ASCII) ; any characters except CTLs, DQUOTE, SOLIDUS, and TILDE
Figure 2: 벤더 전용 프로퍼티 이름의 ABNF 규칙
벤더 전용 프로퍼티 값은 어떤 유효한 JSON 값이든 될 수 있으며 명명 제한은 그러한 값에 적용되지 않는다. 특히 프로퍼티 값이 JSON 객체라면 그 객체의 키가 벤더 전용 프로퍼티 형식으로 명명될 필요는 없다. Figure 3이 이를 보여준다.
"example.com:foo": "bar","example.com:foo2": { "bar": "baz"}
1.8.2. 벤더 전용 값
일부 JSContact IANA 등록 프로퍼티는 벤더 전용 값을 허용한다. 예를 들어 “kind”(Section 2.1.4) 프로퍼티는 표준 값을 열거하지만 임의의 벤더 전용 값도 허용한다. 그러한 벤더 전용 값은 Section 1.8.1에 정의된 유효한 “v-extension” 값이어야 한다(MUST). Figure 4이 이를 보여준다.
"kind": "example.com:baz"
벤더 전용 값이 다른 시스템에도 유용한 것으로 판명되면 벤더는 새로운 표준 값으로 지정할 것을 강하게 권고한다.
1.9. 버전 관리
JSContact Card(Section 2)의 각 인스턴스는 IANA 등록 프로퍼티와 값이 어떤 JSContact 버전을 기반으로 하는지 나타낸다. 버전은 Card 안의 version(Section 2.1.2) 프로퍼티와 JSContact 미디어 타입의 version(Section 3.1) 파라미터 모두에 표시된다. 모든 IANA 등록 요소는 자신이 도입되거나 폐기된 버전을 나타낸다.
JSContact 버전은 major 버전과 minor 버전으로 구성된다.
major 버전 값이 다르면 JSContact 의미 체계와 형식에 상당한 차이가 있음을 뜻한다. 구현체는 프로퍼티 정의와 기타 JSContact 요소가 하위 호환되지 않는 방식으로 달라질 수 있음에 대비해야 한다(MUST).
minor 버전 값의 차이는 JSContact 데이터를 풍부하게 하지만 하위 호환되지 않는 변경을 도입하지 않는 추가 사항을 의미한다. 일반적으로 새로운 프로퍼티 열거형 값이나 좁은 의미 범위의 프로퍼티가 이에 해당한다. 새로운 minor 버전은 구현체가 JSContact 데이터 처리 방식을 변경하도록 요구해서는 안 된다(MUST NOT). major 버전 번호를 변경하면 minor 버전 번호는 0으로 재설정된다.
1.9.1. 버전 형식과 요구사항
버전 값은 숫자 major 버전으로 시작하고 FULL STOP 문자(U+002E), 숫자 minor 버전이 뒤따른다. 이후 버전은 이전 버전보다 수치적으로 크며 major 버전이 minor 버전보다 더 중요한 자릿수로 취급된다. 버전 값은 다음 ABNF로 생성된다.
jsversion = 1\*DIGIT "." 1\*DIGIT
Figure 5: JSContact 버전 값의 ABNF
1.9.2. 현재 버전
이 명세는 JSContact 버전 값 “1.0”을 등록한다(Table 1).
2. Card
이 절은 JSContact 객체 타입 Card를 정의한다. Card는 일반적으로 사람, 조직 또는 회사의 연락처 정보를 저장한다.
미디어 타입은 Section 3.1에 정의되어 있다.
Figure 6은 사람 “John Doe”에 대한 기본 Card를 보여준다. 이 객체는 JSON 데이터의 최상위 객체이므로 Section 1.3.4의 규칙에 따라 @type 프로퍼티가 설정되어 있다.
{ "@type": "Card", "version": "1.0", "uid": "22B2C7DF-9120-4969-8460-05956FE6B065", "kind": "individual", "name": { "components": \[ { "kind": "given", "value": "John" }, { "kind": "surname", "value": "Doe" } \], "isOrdered": true }}
2.1. 메타데이터 프로퍼티
이 절은 Card 인스턴스의 고유 식별자, 생성일, 다른 Card와의 관계 및 기타 메타데이터 정보 등 이 Card 인스턴스에 관한 프로퍼티를 정의한다.
2.1.1. @type
@type: String (mandatory).
Card 객체의 JSContact 타입. 값은 “Card”여야 한다(MUST).
2.1.2. version
version: String (mandatory).
이 Card의 JSContact 버전. 값은 version 프로퍼티에 대해 IANA에 등록된 JSContact Version 값 중 하나여야 한다(MUST). Section 1.9.2도 참조.
"version": "1.0"
2.1.3. created
created: UTCDateTime (optional).
Card가 생성된 날짜와 시간.
"created": "2022-09-30T14:35:10Z"
2.1.4. kind
kind: String (optional; default: “individual”).
Card가 나타내는 엔터티의 종류.
열거형(Section 1.7.5) 값은 다음과 같다.
- individual: 한 사람
- group: 사람 또는 엔터티의 그룹
- org: 조직
- location: 이름이 있는 위치
- device: 가전제품, 컴퓨터, 네트워크 요소 등의 장치
- application: 소프트웨어 애플리케이션
"kind": "individual"
2.1.5. language
language: String (optional).
Card의 텍스트에 사용된 언어를 가장 잘 설명하는 [RFC5646]의 언어 태그이며, script 같은 추가 정보를 선택적으로 포함할 수 있다. 값은 localizations(Section 2.7.1) 프로퍼티에서 지역화할 수 있다(MAY).
"language": "de-AT"
2.1.6. members
members: String[Boolean] (optional).
이 group Card의 멤버인 Card 집합. 집합의 각 키는 멤버의 uid 프로퍼티 값이며 각 불리언 값은 true여야 한다(MUST). 이 프로퍼티가 설정되면 kind 프로퍼티 값은 group이어야 한다(MUST).
그 역은 성립하지 않는다. group Card는 일반적으로 그룹 멤버를 지정하기 위해 members 프로퍼티를 포함하지만 필수는 아니다. members가 없는 group Card는 추상적인 그룹 또는 멤버가 경험적으로 알려진 그룹(예: “IETF Participants”)으로 간주할 수 있다.
"kind": "group","name": { "full": "The Doe family"},"uid": "urn:uuid:ab4310aa-fa43-11e9-8f0b-362b9e155667","members": { "urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af": true, "urn:uuid:b8767877-b4a1-4c70-9acc-505d3819e519": true}
2.1.7. prodId
prodId: String (optional).
Card를 생성한 제품의 식별자. 설정하는 경우 값은 최소 한 글자 이상이어야 한다(MUST).
"prodId": "ACME Contacts App version 1.23.5"
2.1.8. relatedTo
relatedTo: String[Relation] (optional).
이 Card와 관련된 Card 객체 집합. 값은 맵이며 각 키는 관련 Card의 uid 프로퍼티 값이고 값은 관계를 정의한다.
Relation 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Relation”이어야 한다(MUST).
relation: String[Boolean] (optional; default: empty Object).
관련 Card가 이 Card와 맺는 관계를 관계 타입 집합으로 정의한다. 집합의 키가 관계 타입을 정의하며 각 키의 값은 true여야 한다(MUST). 집합이 비어 있으면 두 객체 사이의 관계는 정의되지 않는다.
초기 열거형(Section 1.7.5) 관계 타입 목록은 vCard RELATED 프로퍼티([RFC6350] Section 6.6.6)의 IANA 등록 TYPE [IANA-vCard] 파라미터 값과 일치한다.
- acquaintance
- agent
- child
- co-resident
- co-worker
- colleague
- contact
- crush
- date
- emergency
- friend
- kin
- me
- met
- muse
- neighbor
- parent
- sibling
- spouse
- sweetheart
"relatedTo": { "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6": { "relation": { "friend": true } }, "8cacdfb7d1ffdb59@example.com": { "relation": {} }}
2.1.9. uid
uid: String (mandatory).
서로 다른 시스템, 주소록, 뷰에서 객체를 동일한 것으로 연결하는 식별자. 값은 URN [RFC8141]이어야 하는 것이 권고된다(SHOULD). 다만 [RFC6350]과의 호환성을 위해 URI [RFC3986] 또는 자유 텍스트 값일 수도 있다(MAY). URN 값은 uuid 네임스페이스 [RFC9562]를 사용하는 것이 권고된다(SHOULD). [RFC9562]는 여러 버전의 Universally Unique IDentifier(UUID)를 설명하며 UUID version 4가 권고된다(RECOMMENDED).
"uid": "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
2.1.10. updated
updated: UTCDateTime (optional).
Card의 데이터가 마지막으로 수정된 날짜와 시간.
"updated": "2021-10-31T22:27:10Z"
2.2. 이름 및 조직 프로퍼티
이 절은 Card가 나타내는 엔터티의 이름과 관련 조직 및 역할을 정의하는 프로퍼티를 다룬다. 또한 말하거나 글로 쓸 때 Card가 나타내는 엔터티를 어떻게 지칭할지도 설명한다.
2.2.1. name
name: Name (optional).
Card가 나타내는 엔터티의 이름. 어떤 종류의 이름이든 될 수 있으며, 예를 들어 사람의 법적 이름일 수도 있지만 반드시 그럴 필요는 없다.
2.2.1.1. Name 객체
Name 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Name”이어야 한다(MUST).
components: NameComponent[] (optional).
이 이름을 구성하는 components(Section 2.2.1.2). full 프로퍼티가 설정되지 않았다면 components를 설정해야 하며(MUST), full이 있더라도 설정하는 것이 권고된다(SHOULD). 컴포넌트 목록에는 kind 프로퍼티 값이 separator가 아닌 엔트리가 적어도 하나 있어야 한다(MUST).
Name 컴포넌트는 각 값을 String으로 이어 붙였을 때 해당 엔터티의 유효한 full name이 되도록 순서를 정하는 것이 권고된다(SHOULD). 그런 경우 구현체는 isOrdered 프로퍼티 값을 true로 설정해야 한다(MUST).
이름 컴포넌트가 순서화되어 있다면 defaultSeparator 프로퍼티와 kind 값이 separator인 name 컴포넌트는 컴포넌트 사이에 삽입할 문자에 대한 지침을 제공한다. 다만 구현체는 다른 문자를 자유롭게 선택할 수 있다. separator가 없을 때는 name 컴포넌트 값 사이에 공백 한 글자를 삽입하는 것이 좋은 선택이다.
반대로 name 컴포넌트에 특정 순서가 없다면 isOrdered 프로퍼티 값은 false여야 하고(MUST), components에는 kind 값이 separator인 NameComponent가 포함되어서는 안 되며(MUST NOT), defaultSeparator 프로퍼티도 설정되어서는 안 된다(MUST NOT).
Figure 16은 “Vincent van Gogh” 이름의 예를 보여준다. 하나의 name component 값이 여러 단어로 구성될 수 있음에 유의한다.
"name": { "components": \[ { "kind": "given", "value": "Vincent" }, { "kind": "surname", "value": "van Gogh" } \], "isOrdered": true}
Figure 16: 두 단어로 이루어진 surname의 예
Figure 17은 스페인어권 이름처럼 두 번째 surname을 가진 이름을 보여준다. 추가 예는 Figures 19와 39에 있다.
"name": { "components": \[ { "kind": "given", "value": "Diego" }, { "kind": "surname", "value": "Rivera" }, { "kind": "surname2", "value": "Barrientos" } \], "isOrdered": true}
isOrdered: Boolean (optional; default: “false”).
components 프로퍼티의 name 컴포넌트가 순서화되어 있는지를 나타내는 값.
defaultSeparator: String (optional).
모든 name 컴포넌트 값을 하나의 String으로 연결할 때 name component 값 사이에 삽입할 기본 separator. NameComponent(Section 2.2.1.2) 객체의 kind 값 separator 정의도 참조. Name의 isOrdered가 false이거나 components가 설정되지 않았다면 defaultSeparator를 설정해서는 안 된다(MUST NOT).
full: String (optional).
Name의 완전한 이름 표현. components가 설정되지 않았다면 full 프로퍼티를 설정해야 한다(MUST).
"full": "Mr. John Q. Public, Esq."
sortAs: String[String] (optional).
name component 타입을 기준으로 다른 이름과 비교할 때 이름을 사전식으로 정렬하는 데 사용할 값. 맵의 키는 name component 타입을 정의하고, 값은 해당 타입으로 정렬할 때 그대로 비교할 문자열을 정의한다. 키가 없으면 그 name component 타입은 정렬 시 고려하지 않는 것이 권고된다(SHOULD NOT). 해당 키가 없는 타입으로 정렬하거나 sortAs 프로퍼티 자체가 없을 때의 정렬 방식은 구현체에 따라 다르다. components가 설정되지 않았다면 sortAs를 설정해서는 안 된다(MUST NOT).
맵의 각 키는 아래 NameComponent 객체의 kind 프로퍼티에 정의된 유효한 name component 타입 값이어야 한다(MUST). 맵의 각 키에 대해, name의 components 프로퍼티에는 해당 타입을 가진 NameComponent 객체가 적어도 하나 존재해야 한다(MUST).
Figure 19는 sortAs 프로퍼티 사용을 보여준다. 값은 surname으로 정렬할 때 middle name 뒤에 두 surname을 이어 사용하도록 나타낸다. middle이 없다는 것은 middle name 자체로는 정렬에서 무시해야 함을 나타낸다. 이름에 given name 컴포넌트가 하나만 있어도 sortAs는 given name 기준 정렬 방법을 명시적으로 정의한다. 그렇지 않으면 그 기준의 정렬은 정의되지 않는다.
phoneticScript: String (optional).
NameComponent phonetic 프로퍼티 값에 사용된 script. 자세한 내용은 Section 1.5.4, 예시는 Figure 20 참조.
phoneticSystem: String (optional).
NameComponent phonetic 프로퍼티 값에 사용된 음성 체계. 자세한 내용은 Section 1.5.4, 예시는 Figure 20 참조.
"name": { "components": \[ { "kind": "given", "value": "Robert" }, { "kind": "given2", "value": "Pau" }, { "kind": "surname", "value": "Shou Chang" } \], "sortAs": { "surname": "Pau Shou Chang", "given": "Robert" }, "isOrdered": true}
{ "@type": "Card", "language": "zh-Hant", "name": { "components": \[ { "kind": "surname", "value": "孫" }, { "kind": "given", "value": "中山" }, { "kind": "given2", "value": "文" }, { "kind": "given2", "value": "逸仙" } \] }, "localizations": { "yue": { "name/phoneticSystem": "jyut", "name/phoneticScript": "Latn", "name/components/0/phonetic": "syun1", "name/components/1/phonetic": "zung1saan1", "name/components/2/phonetic": "man4", "name/components/3/phonetic": "jat6sin1" } }}
Figure 20: phonetic 및 localizations 프로퍼티의 예
2.2.1.2. NameComponent
NameComponent 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “NameComponent”여야 한다(MUST).
value: String (mandatory).
name component의 값. “Poe” 또는 “van Gogh”처럼 한 단어 또는 여러 단어로 구성될 수 있다.
kind: String (mandatory).
name component의 종류. 열거형(Section 1.7.5) 값은 다음과 같다.
- title: “Mr.”, “Ms.”, “Dr.” 같은 경칭(title) 또는 접두 호칭.
- given: given name. “first name” 또는 “personal name”이라고도 한다.
- given2: middle name 또는 patronymic name처럼 given과 surname 사이에 나타나는 이름.
- surname: surname. “last name” 또는 “family name”이라고도 한다.
- surname2: 일부 문화권에서 사용하는 두 번째 surname. “maternal surname”이라고도 한다.
- credential: 자격/칭호 접미사. “accreditation qualifier” 또는 “honorific suffix”라고도 하며 예: “B.A.”, “Esq.”.
- generation: 세대 표시자 또는 한정자. 예: “Jr.”, “III”.
- separator: 순서화된 두 non-separator name 컴포넌트 사이의 서식 separator. 컴포넌트의
value에는 하이픈 또는 빈 문자열 등 separator 자체가 그대로 들어간다. 이 값은 Name의defaultSeparator보다 우선한다. 구현체는 연속된 separator 컴포넌트 두 개를 삽입해서는 안 되며(MUST NOT), 대신 합쳐진 값을 가진 하나의 separator 컴포넌트를 삽입하는 것이 권고된다(SHOULD). Name의isOrdered가false이면 이 component kind를 설정해서는 안 된다(MUST NOT).
phonetic: String (optional).
name component의 발음. 이 프로퍼티가 설정되면 Name 객체의 phoneticSystem 또는 phoneticScript 중 적어도 하나를 설정해야 한다(MUST). Section 1.5.4도 참조.
2.2.2. nicknames
nicknames: Id[Nickname] (optional).
Card가 나타내는 엔터티의 별명.
Nickname 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Nickname”이어야 한다(MUST).
name: String (mandatory).
별명.
contexts: String[Boolean] (optional).
별명을 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
다른 별명과 비교한 이 별명의 선호도. Section 1.5.3도 참조.
"nicknames": { "k391": { "name": "Johnny" }}
2.2.3. organizations
organizations: Id[Organization] (optional).
Card와 연관된 회사 또는 조직 이름과 조직 단위.
Organization 객체는 다음 프로퍼티를 가지며 name 또는 units 중 적어도 하나를 설정해야 한다(MUST).
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Organization”이어야 한다(MUST).
name: String (optional).
조직의 이름.
units: OrgUnit[] (optional).
조직 단위 목록. 계층이 높은 순서에서 낮은 순서로 정렬된다(예: 지리적/기능적 division이 그 division 안의 department보다 먼저 온다). 설정하는 경우 목록에는 적어도 하나의 엔트리가 있어야 한다(MUST).
sortAs: String (optional).
이름으로 다른 조직과 비교할 때 조직을 사전식으로 정렬하는 데 사용할 값. 값은 그대로 비교할 문자열을 정의한다. 이 프로퍼티가 없으면 name 프로퍼티 값을 비교에 사용할 수 있다(MAY).
contexts: String[Boolean] (optional).
조직과의 연관이 적용되는 컨텍스트. 예를 들어 합창단 멤버십은 개인 컨텍스트에서만 적용될 수 있다. Section 1.5.1도 참조.
OrgUnit 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “OrgUnit”이어야 한다(MUST).
name: String (mandatory).
조직 단위의 이름.
sortAs: String (optional).
같은 계층 수준의 다른 조직 단위와 이름으로 비교할 때 사전식 정렬에 사용할 값. 계층 수준은 Organization 객체의 units 프로퍼티에서 조직 단위의 배열 인덱스로 정의된다. 값은 그대로 비교할 문자열을 정의한다. 이 프로퍼티가 없으면 name 프로퍼티 값을 비교에 사용할 수 있다(MAY).
"organizations": { "o1": { "name": "ABC, Inc.", "units": \[ { "name": "North American Division" }, { "name": "Marketing" } \], "sortAs": "ABC" }}
Figure 22: organizations 프로퍼티의 예
2.2.4. speakToAs
speakToAs: SpeakToAs (optional).
Card가 나타내는 엔터티를 어떻게 호칭하고, 말로 부르고, 지칭할지 안내하는 정보.
SpeakToAs 객체는 다음 프로퍼티를 가지며 grammaticalGender와 pronouns 중 적어도 하나를 설정해야 한다(MUST).
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “SpeakToAs”여야 한다(MUST).
grammaticalGender: String (optional).
인사말 및 기타 문법적 구조에서 사용할 문법적 성. 예를 들어 독일어에서는 “Sehr geehrte”(feminine)와 “Sehr geehrter”(masculine)처럼 인사말에서 문법적 성을 구분한다. 열거형(Section 1.7.5) 값은 다음과 같다.
- animate
- common
- feminine
- inanimate
- masculine
- neuter
문법적 성만으로 연락처의 성 정체성이나 출생 시 지정된 성을 추론할 수 없다는 점에 유의한다.
pronouns: Id[Pronouns] (optional).
연락처가 스스로 사용하기로 선택한 대명사.
Pronouns 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Pronouns”여야 한다(MUST).
pronouns: String (mandatory).
대명사. 어떤 값이나 형식도 허용한다. 영어 예로 “she/her”, “they/them/theirs”가 있다. 값은 localizations(Section 2.7.1) 프로퍼티에서 덮어쓸 수 있다(MAY).
contexts: String[Boolean] (optional).
대명사를 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
같은 컨텍스트의 다른 대명사와 비교한 이 대명사의 선호도. Section 1.5.3도 참조.
"speakToAs": { "grammaticalGender": "neuter", "pronouns": { "k19": { "pronouns": "they/them", "pref": 2 }, "k32": { "pronouns": "xe/xir", "pref": 1 } }}
2.2.5. titles
titles: Id[Title] (optional).
Card가 나타내는 엔터티의 직함(job title) 또는 기능적 직위(functional position).
Title 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Title”이어야 한다(MUST).
name: String (mandatory).
Card가 나타내는 엔터티의 직함 또는 역할 이름.
kind: String (optional; default: “title”).
직함의 조직적 또는 상황적 종류. 일부 조직과 개인은 조직상 직위인 _title_과 프로젝트 관리 등의 더 일시적인 할당인 _role_을 구분한다.
열거형(Section 1.7.5) 값은 다음과 같다.
- title
- role
organizationId: Id (optional).
이 직함을 보유한 조직의 식별자.
"titles": { "le9": { "kind": "title", "name": "Research Scientist" }, "k2": { "kind": "role", "name": "Project Leader", "organizationId": "o2" }},"organizations": { "o2": { "name": "ABC, Inc." }}
2.3. 연락 프로퍼티
이 절은 Card가 나타내는 엔터티에게 연락하는 방법을 정의하는 프로퍼티를 다룬다.
2.3.1. emails
emails: Id[EmailAddress] (optional).
Card가 나타내는 엔터티에게 연락할 이메일 주소.
EmailAddress 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “EmailAddress”여야 한다(MUST).
address: String (mandatory).
이메일 주소. [RFC5322]의 Section 3.4.1에 정의된 addr-spec 값이어야 한다(MUST).
contexts: String[Boolean] (optional).
이 이메일 주소를 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
다른 이메일 주소와 비교한 이 이메일 주소의 선호도. Section 1.5.3도 참조.
label: String (optional).
값에 대한 사용자 정의 레이블. Section 1.5.2도 참조.
"emails": { "e1": { "contexts": { "work": true }, "address": "jqpublic@xyz.example.com" }, "e2": { "address": "jane\_doe@example.com", "pref": 1 }}
2.3.2. onlineServices
onlineServices: Id[OnlineService] (optional).
Card가 나타내는 엔터티와 연관된 온라인 서비스. 메시징 서비스, 소셜 미디어 프로필 및 기타 서비스일 수 있다.
OnlineService 객체는 다음 프로퍼티를 가지며 uri 또는 user 중 적어도 하나를 설정해야 한다(MUST).
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “OnlineService”여야 한다(MUST).
service: String (optional).
온라인 서비스 또는 프로토콜의 이름. 서비스 웹사이트, 앱 또는 출판물에서 사용하는 대소문자를 그대로 사용할 수 있지만(MAY), 이름은 대소문자를 구분하지 않고 일치하면 같은 것으로 간주해야 한다(MUST). 예: “GitHub”, “kakao”, “Mastodon”.
uri: String (optional).
온라인 서비스에서 Card가 나타내는 엔터티의 식별자. [RFC3986]의 Section 3에 정의된 _URI_여야 한다(MUST).
user: String (optional).
온라인 서비스에서 Card가 나타내는 엔터티의 이름. 어떤 자유 텍스트 값도 허용된다. service 프로퍼티를 설정하는 것이 권고된다(SHOULD).
contexts: String[Boolean] (optional).
서비스를 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
다른 서비스와 비교한 이 서비스의 선호도. Section 1.5.3도 참조.
label: String (optional).
값에 대한 사용자 정의 레이블. Section 1.5.2도 참조.
"onlineServices": { "x1": { "uri": "xmpp:alice@example.com" }, "x2": { "service": "Mastodon", "user": "@alice@example2.com", "uri": "https://example2.com/@alice" }}
Figure 26: onlineServices 프로퍼티의 예
2.3.3. phones
phones: Id[Phone] (optional).
Card가 나타내는 엔터티에게 연락할 전화번호.
Phone 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Phone”이어야 한다(MUST).
number: String (mandatory).
URI 또는 자유 텍스트로 표현한 전화번호. 일반적인 URI scheme은 “tel” [RFC3966] 또는 “sip” [RFC3261]이지만 어떤 URI scheme도 허용한다.
features: String[Boolean] (optional).
전화번호를 사용할 수 있는 연락 기능의 집합. 객체로 표현하며 각 키가 method type이고 불리언 값은 true여야 한다(MUST). 열거형(Section 1.7.5) method type 값은 다음과 같다.
- mobile: 휴대전화용 번호.
- voice: 음성 통화를 지원하는 번호.
- text: 문자 메시지(SMS)를 지원하는 번호.
- video: 화상 회의를 지원하는 번호.
- main-number: 개별 직원의 직통번호가 아니라 회사 안내 데스크 번호 같은 대표 전화번호.
- textphone: 청각 또는 언어 장애인을 위한 장치의 번호.
- fax: 팩스 전송을 지원하는 번호.
- pager: 호출기(pager/beeper) 번호.
contexts: String[Boolean] (optional).
번호를 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
다른 번호와 비교한 이 번호의 선호도. Section 1.5.3도 참조.
label: String (optional).
값에 대한 사용자 정의 레이블. Section 1.5.2도 참조.
"phones": { "tel0": { "contexts": { "private": true }, "features": { "voice": true }, "number": "tel:+1-555-555-5555;ext=5555", "pref": 1 }, "tel3": { "contexts": { "work": true }, "number": "tel:+1-201-555-0123" }}
2.3.4. preferredLanguages
preferredLanguages : Id[LanguagePref] (optional).
Card와 연관된 엔터티에게 연락할 때 선호하는 언어.
LanguagePref 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “LanguagePref”여야 한다(MUST).
language: String (mandatory).
선호 언어. [RFC5646]에 정의된 언어 태그여야 한다(MUST).
contexts: String[Boolean] (optional).
언어를 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
같은 컨텍스트의 다른 언어와 비교한 이 언어의 선호도. Section 1.5.3도 참조.
"preferredLanguages": { "l1": { "language": "en", "contexts": { "work": true }, "pref": 1 }, "l2": { "language": "fr", "contexts": { "work": true }, "pref": 2 }, "l3": { "language": "fr", "contexts": { "private": true } }}
Figure 28: preferredLanguages 프로퍼티의 예
2.4. 캘린더 및 스케줄링 프로퍼티
이 절은 Card가 나타내는 엔터티와 캘린더 이벤트 일정을 잡기 위한 프로퍼티를 정의한다.
2.4.1. calendars
calendars: Id[Calendar] (optional).
free-busy 정보를 조회하는 용도 등을 포함한 Card가 나타내는 엔터티의 캘린더 리소스.
Calendar 객체는 Resource(Section 1.4.4) 데이터 타입의 모든 프로퍼티를 가지며 다음 추가 정의가 적용된다.
@type프로퍼티를 설정하는 경우 값은 “Calendar”여야 한다(MUST).kind프로퍼티는 mandatory이다. 열거형(Section 1.7.5) 값은 다음과 같다.- calendar: 캘린더 이벤트나 작업 같은 엔트리를 포함하는 캘린더 리소스.
- freeBusy: 예를 들어 그룹 이벤트의 일정을 잡기 위해 free-busy 조회를 허용하는 리소스.
"calendars": { "calA": { "kind": "calendar", "uri": "webcal://calendar.example.com/calA.ics" }, "project-a": { "kind": "freeBusy", "uri": "https://calendar.example.com/busy/project-a" }}
2.4.2. schedulingAddresses
schedulingAddresses: Id[SchedulingAddress] (optional).
엔터티가 캘린더 스케줄링 초대를 받을 수 있는 스케줄링 주소.
SchedulingAddress 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “SchedulingAddress”여야 한다(MUST).
uri: String (mandatory).
연락처와 캘린더 일정을 잡는 데 사용할 주소. [RFC3986]의 Section 3에 정의된 URI여야 한다(MUST).
contexts: String[Boolean] (optional).
스케줄링 주소를 사용할 컨텍스트. Section 1.5.1도 참조.
pref: UnsignedInt (optional).
다른 스케줄링 주소와 비교한 이 스케줄링 주소의 선호도. Section 1.5.3도 참조.
label: String (optional).
스케줄링 주소에 대한 사용자 정의 레이블. Section 1.5.2도 참조.
"schedulingAddresses": { "sched1": { "uri": "mailto:janedoe@example.com" }}
Figure 30: schedulingAddresses 프로퍼티의 예
2.5. 주소 및 위치 프로퍼티
이 절은 Card가 나타내는 엔터티와 연관된 우편 주소와 지리적 위치를 위한 프로퍼티를 정의한다.
2.5.1. addresses
addresses: Id[Address] (optional).
Card가 나타내는 엔터티의 주소. 우편 주소 또는 지리적 위치 등이 포함된다.
2.5.1.1. Address 객체
Address 객체는 다음 프로퍼티를 가지며 components, coordinates, countryCode, full, timeZone 중 적어도 하나를 설정해야 한다(MUST).
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Address”여야 한다(MUST).
components: AddressComponent[] (optional).
주소를 구성하는 components(Section 2.5.1.2). 컴포넌트 목록에는 kind 값이 separator가 아닌 엔트리가 적어도 하나 있어야 한다(MUST).
Address 컴포넌트는 값을 String으로 연결했을 때 유효한 full address가 되도록 순서를 정하는 것이 권고된다(SHOULD). 그런 경우 구현체는 isOrdered 값을 true로 설정해야 한다(MUST).
주소 컴포넌트가 순서화되어 있다면 defaultSeparator와 kind 값이 separator인 address 컴포넌트는 컴포넌트 사이에 삽입할 문자에 대한 지침을 제공하지만 구현체는 다른 문자를 자유롭게 선택할 수 있다. separator가 없을 때 address component 값 사이에 공백 한 글자를 삽입하는 것이 좋은 선택이다.
반대로 address 컴포넌트에 특정 순서가 없다면 isOrdered는 false여야 하며(MUST), components에 kind가 separator인 AddressComponent를 포함해서는 안 되고(MUST NOT), defaultSeparator도 설정해서는 안 된다(MUST NOT).
isOrdered: Boolean (optional; default: “false”).
components 프로퍼티의 address 컴포넌트가 순서화되어 있는지를 나타낸다.
countryCode: String (optional).
Alpha-2 국가 코드 [ISO.3166-1].
coordinates: String (optional).
주소의 geo: URI [RFC5870].
timeZone: String (optional).
주소가 위치한 시간대. IANA Time Zone Database [IANA-TZ]에 등록된 시간대 이름이어야 한다(MUST).
contexts: String[Boolean] (optional).
이 주소를 사용할 컨텍스트. 불리언 값은 true여야 한다(MUST). 공통 컨텍스트(Section 1.5.1) 외에 다음 키 값을 허용한다.
- billing: 청구에 사용할 주소.
- delivery: 물리적 물품 배송에 사용할 주소.
full: String (optional).
도로, 지역 또는 국가를 포함하는 전체 주소. 이 프로퍼티의 목적은 개별 주소 컴포넌트를 알지 못하더라도 주소를 정의할 수 있게 하는 것이다.
defaultSeparator: String (optional).
모든 address component 값을 하나의 String으로 연결할 때 address component 값 사이에 삽입할 기본 separator. AddressComponent(Section 2.5.1.2) 객체의 kind 값 separator 정의도 참조. Address의 isOrdered가 false이거나 components가 설정되지 않았다면 defaultSeparator를 설정해서는 안 된다(MUST NOT).
pref: UnsignedInt (optional).
다른 주소와 비교한 이 주소의 선호도. Section 1.5.3도 참조.
phoneticScript: String (optional).
AddressComponent phonetic 프로퍼티 값에 사용된 script. Section 1.5.4도 참조.
phoneticSystem: String (optional).
AddressComponent phonetic 프로퍼티 값에 사용된 음성 체계. Section 1.5.4도 참조.
다음 예시는 “54321 Oak St, Reston, CA 20190, USA”에 대한 address 프로퍼티 사용을 보여준다. 추가 예는 Section 2.5.1.3에 있다.
"addresses": { "k23": { "contexts": { "work": true }, "components": \[ { "kind": "number", "value": "54321" }, { "kind": "separator", "value": " " }, { "kind": "name", "value": "Oak St" }, { "kind": "locality", "value": "Reston" }, { "kind": "region", "value": "VA" }, { "kind": "separator", "value": " " }, { "kind": "postcode", "value": "20190" }, { "kind": "country", "value": "USA" } \], "countryCode": "US", "defaultSeparator": ", ", "isOrdered": true }}
2.5.1.2. AddressComponent 객체
AddressComponent 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “AddressComponent”여야 한다(MUST).
value: String (mandatory).
address component의 값.
kind: String (mandatory).
address component의 종류. 열거형(Section 1.7.5) 값은 다음과 같다.
- room: 방, suite 번호 또는 식별자.
- apartment: 아파트 번호, unit, box 번호 같은 확장 지정.
- floor: 주소가 위치한 층 또는 레벨.
- building: 주소가 위치한 건물, 타워 또는 콘도미니엄.
- number: 도로 번호. 예: “123”. 숫자 값으로 제한되지 않으며 범위(“112-10”), grid style(“39.2 RD”), 영숫자(“N6W23001”), 분수(“123 1/2”) 등 어떤 값도 포함할 수 있다.
- name: 도로명.
- block: block 이름 또는 번호.
- subdistrict: 하위 행정구역, ward 또는 district의 기타 하위 단위.
- district: district 이름.
- locality: municipality, city, town, village, post town 또는 기타 locality.
- region: province, state, prefecture, county, canton 같은 행정 구역.
- postcode: 해당 국가 우편 시스템이 주소에 부여하는 postal code, post code, ZIP code 또는 기타 짧은 코드.
- country: 국가명.
- direction: 방위 또는 quadrant. 예: “north”.
- landmark: 도로명과 번호를 대체할 수 있는, 대중에게 알려진 눈에 띄는 지형/시설. 예: “White House”, “Taj Mahal”.
- postOfficeBox: 사서함 번호 또는 식별자.
- separator: 순서화된 두 non-separator address 컴포넌트 사이의 서식 separator.
value에는 하이픈 또는 빈 문자열 같은 separator 자체가 그대로 들어간다. 이 값은 Address의defaultSeparator보다 우선한다. 구현체는 연속된 separator 컴포넌트 두 개를 삽입해서는 안 되며(MUST NOT), 대신 합쳐진 값을 가진 하나의 separator 컴포넌트를 삽입하는 것이 권고된다(SHOULD). Address의isOrdered가false이면 이 component kind를 설정해서는 안 된다(MUST NOT).
phonetic: String (optional).
address component의 발음. 이 프로퍼티가 설정되면 Address 객체의 phoneticSystem 또는 phoneticScript 중 적어도 하나를 설정해야 한다(MUST). Section 1.5.4도 참조.
2.5.1.3. 추가 주소 예제
다음 예시는 “46, 1 Sukhumvit 51 Alley, Khlong Tan Nuea, Watthana, Bangkok 10110, Thailand”에 대한 address 프로퍼티 사용을 보여준다.
"addresses": { "k25": { "components": \[ { "kind": "number", "value": "46" }, { "kind": "name", "value": "1 Sukhumvit 51 Alley" }, { "kind": "subdistrict", "value": "Khlong Tan Nuea" }, { "kind": "district", "value": " Watthana" }, { "kind": "locality", "value": "Bangkok" }, { "kind": "country", "value": "Thailand" }, { "kind": "postcode", "value": "10110" } \], "defaultSeparator": ", ", "isOrdered": true }}
다음 예시는 “2-7-2 Marunouchi, Chiyoda-ku, Tokyo 100-8994” 주소와 그 일본어 지역화(Section 2.7.1)를 보여준다.
"addresses": { "k26": { "components": \[ { "kind": "block", "value": "2-7" }, { "kind": "separator", "value": "-" }, { "kind": "number", "value": "2" }, { "kind": "separator", "value": " " }, { "kind": "district", "value": "Marunouchi" }, { "kind": "locality", "value": "Chiyoda-ku" }, { "kind": "region", "value": "Tokyo" }, { "kind": "separator", "value": " " }, { "kind": "postcode", "value": "100-8994" } \], "defaultSeparator": ", ", "full": "2-7-2 Marunouchi, Chiyoda-ku, Tokyo 100-8994", "isOrdered": true }},"localizations": { "jp": { "addresses/k26": { "components": \[ { "kind": "region", "value": "東京都" }, { "kind": "locality", "value": "千代田区" }, { "kind": "district", "value": "丸ノ内" }, { "kind": "block", "value": "2-7" }, { "kind": "separator", "value": "-" }, { "kind": "number", "value": "2" }, { "kind": "postcode", "value": "〒100-8994" } \], "defaultSeparator": "", "full": "〒100-8994東京都千代田区丸ノ内2-7-2", "isOrdered": true } }}
2.6. 리소스 프로퍼티
이 절은 Card가 나타내는 엔터티와 연관된 디지털 리소스를 위한 프로퍼티를 정의한다.
2.6.1. cryptoKeys
cryptoKeys: Id[CryptoKey] (optional).
Card가 나타내는 엔터티와 연관된 공개 키, 인증서 같은 암호화 리소스.
CryptoKey 객체는 Resource(Section 1.4.4) 데이터 타입의 모든 프로퍼티를 가지며 다음 추가 정의가 적용된다.
@type프로퍼티를 설정하는 경우 값은 “CryptoKey”여야 한다(MUST).
다음 예시는 외부 암호화 리소스를 참조하는 방법을 보여준다.
"cryptoKeys": { "mykey1": { "uri": "https://www.example.com/keys/jdoe.cer" }}
Figure 34: 외부 데이터를 사용하는 cryptoKeys의 예
다음 예시는 키 데이터를 CryptoKey 안에 임베드하는 방법을 보여준다. 키 데이터는 설명을 위해서만 여러 줄로 표시되어 있다.
"cryptoKeys": { "mykey2": { "uri": "data:application/pgp-keys;base64,LS0tLS1CRUdJTiBSU0EgUFVC TElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQSt4R1ovd2N6OXVnRnBQMDdOc 3BvNlUxN2wwWWhGaUZweHhVNHBUazNMaWZ6OVIzenNJc3UKRVJ3dGE3K2 ZXSWZ4T28yMDhldHQvamhza2lWb2RTRXQzUUJHaDRYQmlweVdvcEt3Wjk zSEhhRFZaQUFMaS8yQQoreFRCdFdkRW83WEdVdWpLRHZDMi9hWkt1a2Zq cE9pVUk4QWhMQWZqbWxjRC9VWjFRUGgwbUhzZ2xSTkNtcEN3Cm13U1hBO VZObWh6K1BpQitEbWw0V1duS1cvVkhvMnVqVFh4cTcrZWZNVTRIMmZueT NTZTNLWU9zRlBGR1oxVE4KUVNZbEZ1U2hXckhQdGlMbVVkUG9QNkNWMm1 NTDF0aytsN0RJSXFYclFoTFVLREFDZU01cm9NeDBrTGhVV0I4UAorMHVq MUNObE5ONEpSWmxDN3hGZnFpTWJGUlU5WjRONll3SURBUUFCCi0tLS0tR U5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K" }}
Figure 35: 임베드 데이터를 사용하는 cryptoKeys의 예
2.6.2. directories
directories: Id[Directory] (optional).
Card가 나타내는 엔터티에 대한 정보를 포함하는 디렉터리.
Directory 객체는 Resource(Section 1.4.4) 데이터 타입의 모든 프로퍼티를 가지며 다음 추가 정의가 적용된다.
@type프로퍼티를 설정하는 경우 값은 “Directory”여야 한다(MUST).kind프로퍼티는 mandatory이다. 열거형(Section 1.7.5) 값은 다음과 같다.- directory: Card가 나타내는 엔터티가 속한 디렉터리 서비스. 일반적으로 회사 디렉터리에서 동료나 관리자처럼 관련 엔터티도 포함하는 조직 디렉터리이다.
- entry: Card가 나타내는 엔터티의 디렉터리 엔트리.
directory타입과 달리 디렉터리 내부에서 해당 엔터티를 가리키는 구체적인 URI이다.
추가로 Directory 객체는 다음 프로퍼티를 갖는다.
listAs: UnsignedInt (optional).
Card 안에서 같은 kind 값을 가진 모든 Directory 객체 목록에서 이 디렉터리 리소스의 위치. 설정하는 경우 listAs 값은 0보다 커야 한다(MUST). 여러 디렉터리 리소스가 같은 listAs 값을 갖거나 아예 갖지 않을 수 있다(MAY). 같은 값을 가진 엔트리의 정렬 방식은 구현체에 따라 다르다.
"directories": { "dir1": { "kind": "entry", "uri": "https://dir.example.com/addrbook/jdoe/Jean%20Dupont.vcf" }, "dir2": { "kind": "directory", "uri": "ldap://ldap.example/o=Example%20Tech,ou=Engineering", "pref": 1 }
Figure 36: directories 프로퍼티의 예
2.6.3. links
links: Id[Link] (optional).
다른 용도별 리소스 프로퍼티에 들어맞지 않는 리소스에 대한 링크.
Link 객체는 Resource(Section 1.4.4) 데이터 타입의 모든 프로퍼티를 가지며 다음 추가 정의가 적용된다.
@type프로퍼티를 설정하는 경우 값은 “Link”여야 한다(MUST).kind프로퍼티는 optional이다. 열거형(Section 1.7.5) 값은 다음과 같다.- contact: Card가 나타내는 엔터티에게 연락할 수 있는 URI인 리소스. 웹 폼이나 사용자 상호작용이 필요한 기타 매체를 포함한다.
"links": { "link3": { "kind": "contact", "uri": "mailto:contact@example.com", "pref": 1 }}
2.6.4. media
media: Id[Media] (optional).
Card가 나타내는 엔터티와 연관된 사진, 아바타, 소리 같은 미디어 리소스.
Media 객체는 Resource(Section 1.4.4) 데이터 타입의 모든 프로퍼티를 가지며 다음 추가 정의가 적용된다.
@type프로퍼티를 설정하는 경우 값은 “Media”여야 한다(MUST).kind프로퍼티는 mandatory이다. 열거형(Section 1.7.5) 값은 다음과 같다.- photo: 사진 또는 아바타인 리소스.
- sound: 예를 들어
name프로퍼티 내용의 올바른 발음을 지정하기 위한 오디오 미디어 리소스. - logo: Card가 나타내는 엔터티와 연관된 그래픽 이미지 또는 로고 리소스.
"media": { "res45": { "kind": "sound", "uri": "CID:JOHNQ.part8.19960229T080000.xyzMail@example.com" }, "res47": { "kind": "logo", "uri": "https://www.example.com/pub/logos/abccorp.jpg" }, "res1": { "kind": "photo", "uri": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4..." }}
2.7. 다국어 프로퍼티
이 절은 Card 내용을 사람의 언어로 지역화하기 위한 프로퍼티를 정의한다.
2.7.1. localizations
localizations: String[PatchObject] (optional).
Card의 주 언어(Section 2.1.5)가 아닌 언어로 지역화된 프로퍼티 값. Localizations는 기존 프로퍼티 값에 대한 언어별 대안을 제공하며 새로운 프로퍼티를 추가하지 않는 것이 권고된다(SHOULD NOT). localizations 프로퍼티 값의 키는 언어 태그 [RFC5646]이며, 값은 PatchObject 타입이고 해당 언어 태그로 Card를 지역화한다. PatchObject의 경로는 localizations를 포함한 Card를 기준으로 한 상대 경로이다. 패치는 localizations 프로퍼티 자체를 대상으로 해서는 안 된다(MUST NOT).
개념적으로 Card는 다음과 같이 지역화된다.
- Card를 지역화할 언어 태그를 결정한다.
localizations프로퍼티에 해당 언어 키가 있으면 PatchObject 값을 얻는다. 그런 키가 없다면 중단한다.- Card의 복사본을 만들되
localizations프로퍼티는 복사하지 않는다. - PatchObject의 모든 패치를 Card 복사본에 적용한다.
- 선택적으로 Card 복사본의
language프로퍼티를 설정한다. - 패치된 Card 복사본을 원본 Card의 지역화 변형으로 사용한다.
PatchObject의 패치는 어떤 값 타입도 포함할 수 있다. 그 값은 패치되는 프로퍼티의 정의에 따라 유효한 값이어야 한다(MUST).
Figure 39는 name 프로퍼티의 전체 내용을 키릴 문자를 사용하는 우크라이나어로 교체해 지역화한다.
{ "name": { "components": \[ { "kind": "title", "value": "Mr." }, { "kind": "given", "value": "Ivan" }, { "kind": "given2", "value": "Petrovich" }, { "kind": "surname", "value": "Vasiliev" } \] }, "localizations": { "uk-Cyrl": { "name": { "components": \[ { "kind": "title", "value": "г-н" }, { "kind": "given", "value": "Иван" }, { "kind": "given2", "value": "Петрович" }, { "kind": "surname", "value": "Васильев" } \] } } }}
Figure 40은 titles 프로퍼티 내부 를 패치하여 title 이름을 지역화한다. Title 객체에서 name 프로퍼티를 제외한 모든 프로퍼티는 그대로 유지된다.
"name": { "full": "Gabriel García Márquez"},"titles": { "t1": { "kind": "title", "name": "novelist" }},"localizations": { "es": { "titles/t1/name": "escritor" }}
2.8. 추가 프로퍼티
이 절은 앞 절들 중 어디에도 적합하지 않은 프로퍼티를 정의한다.
2.8.1. anniversaries
anniversaries: Id[Anniversary] (optional).
Card가 나타내는 엔터티의 기억할 만한 날짜와 이벤트.
Anniversary 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Anniversary”여야 한다(MUST).
kind: String (mandatory).
기념일의 종류. 열거형(Section 1.7.5) 값은 다음과 같다.
- birth: 생일 기념일
- death: 사망일 기념일
- wedding: 결혼기념일
date: PartialDate|Timestamp (mandatory; defaultType: PartialDate).
그레고리력 기준 기념일의 날짜. 완전하거나 부분적인 달력 날짜 또는 완전한 UTC timestamp여야 한다(MUST)(아래 Timestamp 및 PartialDate 객체 타입 정의 참조).
place: Address (optional).
이 기념일과 연관된 주소. 예: 출생지 또는 사망지.
PartialDate 객체는 그레고리력의 완전한 또는 부분적인 달력 날짜를 나타낸다. 완전한 날짜, 연도, 특정 연도의 월, 또는 특정 월의 일을 나타낸다. 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “PartialDate”여야 한다(MUST).
year:
UnsignedInt (optional). 달력 연도.
month: UnsignedInt (optional).
달력의 월. 정수 1 <= month <= 12로 표현한다. 이 프로퍼티가 설정되면 year 또는 day 중 하나를 설정해야 한다(MUST).
day: UnsignedInt (optional).
달력의 월 내 날짜. 해당 월과 연도에서의 유효성에 따라 정수 1 <= day <= 31로 표현한다. 이 프로퍼티가 설정되면 month 프로퍼티를 설정해야 한다(MUST).
calendarScale: String (optional).
이 날짜가 속하는 달력 체계의 소문자 이름. Common Locale Data Repository(CLDR) [RFC7529]에 등록된 달력 체계 이름 또는 벤더 전용 값이어야 한다(MUST). year, month, day는 여전히 그레고리력으로 표현해야 한다(MUST). 그레고리력과 해당 달력 체계 사이에서 날짜를 변환할 때 year 프로퍼티가 필요할 수 있다는 점에 유의한다.
Timestamp 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Timestamp”여야 한다(MUST).
utc: UTCDateTime (mandatory).
UTC 시간의 한 시점.
Figure 41은 partial date와 timestamp를 사용하는 anniversaries를 보여준다. Timestamp 객체 값에는 Section 1.3.4의 규칙에 따라 @type 프로퍼티가 설정되어 있음에 유의한다.
"anniversaries": { "k8": { "kind": "birth", "date": { "year": 1953, "month": 4, "day": 15 } }, "k9": { "kind": "death", "date": { "@type": "Timestamp", "utc": "2019-10-15T23:10:00Z" }, "place": { "full": "4445 Tree Street\\nNew England, ND 58647\\nUSA" } }}
Figure 41: anniversaries 프로퍼티의 예
2.8.2. keywords
keywords: String[Boolean] (optional).
_tags_라고도 부르는 자유 텍스트 키워드 집합. 집합의 각 키가 키워드이고 각 불리언 값은 true여야 한다(MUST).
"keywords": { "internet": true, "IETF": true}
2.8.3. notes
notes: Id[Note] (optional).
Card와 연관된 자유 텍스트 메모.
Note 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Note”여야 한다(MUST).
note: String (mandatory).
이 메모의 자유 텍스트 값.
created: UTCDateTime (optional).
메모가 생성된 날짜와 시간.
author: Author (optional).
이 메모의 작성자.
Author 객체는 다음 프로퍼티를 가지며 @type을 제외한 프로퍼티를 적어도 하나 설정해야 한다(MUST).
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “Author”여야 한다(MUST).
name: String (optional).
작성자의 이름.
uri: String (optional).
작성자를 식별하는 URI 값.
"notes": { "n1": { "note": "Open office hours are 1600 to 1715 EST, Mon-Fri", "created": "2022-11-23T15:01:32Z", "author": { "name": "John" } }}
2.8.4. personalInfo
personalInfo: Id[PersonalInfo] (optional).
Card가 나타내는 엔터티의 개인 정보.
PersonalInfo 객체는 다음 프로퍼티를 갖는다.
@type: String.
객체의 JSContact 타입. 설정하는 경우 값은 “PersonalInfo”여야 한다(MUST).
kind: String (mandatory).
개인 정보의 종류. 열거형(Section 1.7.5) 값은 다음과 같다.
- expertise: 전문 분야 또는 자격
- hobby: 취미
- interest: 관심사
value: String (mandatory).
실제 정보.
level: String (optional).
전문성 수준 또는 취미/관심사에 대한 참여 수준. 열거형(Section 1.7.5) 값은 다음과 같다.
- high
- medium
- low
listAs: UnsignedInt (optional).
Card 안에서 같은 kind 값을 가진 모든 PersonalInfo 객체 목록에서 이 개인 정보의 위치. 설정하는 경우 listAs 값은 0보다 커야 한다(MUST). 여러 personal information 엔트리가 같은 listAs 값을 갖거나 아예 갖지 않을 수 있다(MAY). 같은 값을 가진 엔트리의 정렬 방식은 구현체에 따라 다르다.
label: String (optional).
사용자 정의 레이블. Section 1.5.2 참조.
"personalInfo": { "pi2": { "kind": "expertise", "value": "chemistry", "level": "high" }, "pi1": { "kind": "hobby", "value": "reading", "level": "high" }, "pi6": { "kind": "interest", "value": "r&b music", "level": "medium" }}
Figure 44: personalInfo 프로퍼티의 예
3. IANA 고려사항
3.1. 미디어 타입 등록
이 문서는 JSON으로 형식화된 JSContact 데이터에 사용할 미디어 타입을 정의한다.
Type name:
application
Subtype name:
jscontact+json
Required parameters:
없음
Optional parameters:
version
이 파라미터는 body part에 있는 JSContact 데이터의 버전을 전달한다. 한 번을 초과해 나타나서는 안 된다(MUST NOT). 이 파라미터가 설정되면 body part 안의 모든 JSContact version(Table 2) 프로퍼티 값이 파라미터 값과 일치해야 한다(MUST).
Encoding considerations:
[RFC8259]의 Section 11에 명시된 application/json의 인코딩 고려사항과 동일하다.
Security considerations:
RFC 9553의 Section 4를 참조.
Interoperability considerations:
JSContact는 가능한 한 모호성을 피하도록 설계되었지만, 다른 연락처 형식의 객체를 JSContact로 또는 JSContact에서 다른 형식으로 변환할 때 동일한 논리적 데이터에 서로 다른 표현이 생기거나 해석의 모호성이 발생할 수 있다. 예를 들어 두 객체의 URL 값이 대소문자에서만 다를 때, 두 JSContact 객체가 의미적으로 같은지 여부를 애플리케이션마다 다르게 판단할 수 있다.
Published specification:
RFC 9553
Applications that use this media type:
현재 text/vcard 미디어 타입을 사용하는 애플리케이션은 이를 대안으로 사용할 수 있다.
Fragment identifier considerations:
[RFC6901] Section 6에 정의된 JSON Pointer fragment identifier를 사용할 수 있다.
Additional information:
Magic number(s):
N/A
File extensions(s):
N/A
Macintosh file type code(s):
N/A
Person & email address to contact for further information:
Intended usage:
COMMON
Restrictions on usage:
N/A
Author:
RFC 9553의 “Authors’ Addresses” 절 참조.
Change controller:
IETF
3.2. JSContact 레지스트리 그룹 생성
IANA는 “JSContact” 레지스트리 그룹을 생성했다. 다음 절들에서 정의하는 새로운 레지스트리는 모두 이 그룹에 속한다.
3.3. 레지스트리 정책 및 변경 절차
하위 호환되지 않는(Section 1.9) 변경을 도입하는 레지스트리 할당은 JSContact major 버전을 변경해야 하며, 그 밖의 변경은 minor 버전만 변경하면 된다. JSContact major 버전 변경이 필요한 할당의 레지스트리 정책은 Standards Action([RFC8126], Section 4.9)이다. 그 밖의 할당에 대한 정책은 Specification Required([RFC8126], Section 4.6)이다.
지정 전문가(Designated Expert, DE)는 major 또는 minor 버전 변경이 필요한지 결정하고 새 버전을 “JSContact Version” 레지스트리(Section 3.4)에 할당한다. 버전 번호는 1씩 증가하며 major 버전이 바뀌면 minor 버전은 0으로 재설정된다. 하나의 할당은 여러 변경을 포함하고 여러 레지스트리에 동시에 적용될 수 있으며, 이 경우 한 번의 버전 변경으로 충분하다. 레지스트리 정책이 Specification Required인 경우 DE는 각 레지스트리의 Description 항목에 새 할당을 문서화하는 것으로 충분하다고 판단할 수 있다.
등록에는 “common”, “reserved”, “obsolete” 중 하나의 intended usage가 있어야 한다(MUST).
- “common”은 시스템 간에 공유되는 의미와 구문을 가진 항목을 의미한다. 최신 시스템은 그러한 항목이 JSContact 데이터에 나타날 수 있음을 예상해야 한다(MUST).
- “reserved”는 향후 확장이나 프로토콜 사용과의 이름 충돌을 피하기 위해 의미를 할당하지 않고 항목을 예약한다. 구현체는 해당 항목을 사용하는 프로토콜이나 확장 바깥에서 그런 이름의 항목을 기대하거나 추가해서는 안 된다(MUST NOT). 그렇지 않으면 해당 JSContact 데이터는 유효하지 않다.
- “obsolete”는 최신 시스템이 더 이상 추가하지 않을 것으로 예상되는 항목이다. 일반적으로 그 의미를 대신하는 새로운 할당이 정의되어 있을 수 있다. 구현체는 “Until Version” 레지스트리 필드까지(해당 버전 포함) 그러한 항목이 JSContact 데이터에 나타날 수 있음을 예상해야 한다(MUST). 해당 항목이 폐기된 이후 버전에는 그러한 항목을 추가해서는 안 된다(MUST NOT). 그렇지 않으면 해당 JSContact 데이터는 유효하지 않다.
레지스트리 항목의 intended usage는 버전 사이에 변경될 수 있지만 DE는 변경 전에 기존 구현 및 표준에 미칠 영향을 신중하게 고려해야 한다.
등록 절차는 공식적인 표준화 절차가 아니라 과도한 시간 지연 없이 커뮤니티 의견을 받고 일관성을 확인하기 위한 행정적 절차이다. 원 명세에서 다루지 않은 사용 사례를 위해 벤더가 추가하는 새 항목을 문서화하고 등록하도록 장려하여 상호운용성을 높이도록 설계되었다.
3.3.1. 사전 커뮤니티 검토
새 등록 가능성에 대한 공지는 검토를 위해 Calext WG 메일링 리스트 calsify@ietf.org로 보내야 한다(MUST). 이 메일링 리스트는 제안된 레지스트리 할당에 대한 커뮤니티 피드백을 요청하기에 적합하다.
이 목록에 공개 게시하는 목적은 항목 이름 또는 값의 선택, 설명의 비모호성, 상호운용성 또는 보안 고려사항에 대한 의견과 피드백을 요청하는 것이다. 제출자는 언제든 수정된 등록 제안을 제출하거나 등록을 완전히 포기할 수 있다.
3.3.2. IANA에 요청 제출
등록 요청은 IANA iana@iana.org로 보낼 수 있다.
3.3.3. 지정 전문가 검토
DE의 주요 관심사는 이름 충돌을 방지하고 제출자가 보안 및 개인정보 보호 고려사항을 문서화하도록 장려하는 것이다.
새 타입 이름, 프로퍼티 이름 또는 열거형 값은 이미 등록된 이름이나 값과 대소문자만 달라서는 안 된다(MUST NOT).
common-use 등록의 경우 DE는 상호운용성을 보장할 수 있는 적절한 문서가 제공되는지 확인할 것으로 기대된다. 또한 새 할당이 IETF에서 진행 중이거나 이미 발행된 작업과 충돌하지 않는지 확인해야 한다.
DE는 등록 요청을 승인 또는 거부하고 그 결정을 Calext WG 메일링 리스트 또는 후속 리스트에 공지하며 IANA에도 알린다. 거부 공지는 설명으로 정당화되어야 하며, 가능한 경우 요청을 수용 가능한 형태로 수정하는 구체적인 제안도 제공해야 한다.
3.3.4. 변경 절차
JSContact 레지스트리 그룹 항목이 IANA에 게시된 뒤 Change Controller는 해당 정의의 변경을 요청할 수 있다. 변경 요청은 원래 등록 요청에 적합했을 동일한 절차로 처리한다.
JSContact 등록은 삭제되지 않는다. 더 이상 사용하기 적절하지 않다고 판단되는 항목은 “Intended Usage” 필드를 변경해 obsolete로 선언하며 IANA 레지스트리에 명확히 표시된다.
JSContact 레지스트리 항목 정의의 중요한 변경은 발행된 명세에 심각한 누락 또는 오류가 있을 때에만 요청하는 것이 좋다. 그러한 변경은 상호운용성 문제를 일으킬 수 있기 때문이다. 검토가 필요한 경우, 이전 정의에서는 유효했던 엔터티를 새 정의에서 유효하지 않게 만드는 변경 요청은 거부될 수 있다.
3.4. JSContact Version 레지스트리 생성
IANA는 “JSContact Version” 레지스트리를 생성했다. 이 레지스트리의 목적은 JSContact major 및 minor 버전 번호의 허용 값 범위를 정의하는 것이다.
레지스트리 엔트리는 먼저 “Major Version” 열을 기준으로 숫자 오름차순 정렬하고, “Major Version”이 같으면 “Minor Version” 열을 기준으로 숫자 오름차순 정렬한다.
레지스트리 절차는 Section 3.3에 설명되어 있다.
3.4.1. JSContact Version 레지스트리 템플릿
Major Version:
JSContact major 버전 번호의 숫자 값. 양의 정수여야 한다(MUST).
Highest Minor Version:
해당 major 버전의 JSContact minor 버전 최대 숫자 값. 0 또는 양의 정수여야 한다(MUST). 이 값 이하의 모든 숫자는 해당 major 버전에 유효한 minor 버전 값이다.
3.4.2. JSContact Version 레지스트리 초기 내용
다음 표는 초기의 유효한 major 및 minor 버전 번호 범위를 나열한다.
Table 1: JSContact Version 레지스트리
| Major Version | Highest Minor Version | Reference |
|---|---|---|
| 1 | 0 | RFC 9553 |
3.5. JSContact Properties 레지스트리 생성
IANA는 “JSContact Properties” 레지스트리를 생성했다. 이 레지스트리의 목적은 JSContact 객체 확장의 상호운용성을 가능하게 하는 것이다.
레지스트리 엔트리는 “Property Name”, “Property Context”, “Since Version” 순서로 각 열을 기준으로 알파벳 오름차순 정렬한다. 동일한 엔트리의 순서는 임의이다.
새 프로퍼티의 레지스트리 절차는 Section 3.3에 설명되어 있다.
3.5.1. JSContact Properties 레지스트리 템플릿
Property Name:
프로퍼티 이름. 이 등록의 “Property Context” 필드에 나열된 어떤 객체 타입에도 이미 등록된 이름이어서는 안 된다(MUST NOT). 다른 객체 타입이 동일한 이름의 다른 프로퍼티를 이미 등록했을 수는 있다(MAY). 단 동일 이름은 의미가 유사할 때에만 사용해야 한다(MUST).
Property Type:
intended usage가 “reserved”가 아닌 프로퍼티의 경우 Section 1.3.2에 정의된 타입 시그니처를 사용하는 프로퍼티 타입이다. 프로퍼티 타입은 “JSContact Types” 레지스트리에 등록되어 있어야 한다(MUST). 예약된 프로퍼티 이름의 경우 값은 정확히 “not applicable” 문자열이어야 한다(MUST).
Property Context:
프로퍼티를 포함하는 JSContact 객체 타입(Section 3.6.2)의 쉼표로 구분된 목록. 예약된 프로퍼티 이름의 경우 값은 정확히 “not applicable”일 수 있다(MAY).
Intended Usage:
“common”, “reserved”, “obsolete” 중 하나일 수 있다.
Since Version:
프로퍼티 정의가 기반하는 JSContact 버전. “JSContact Version” 레지스트리(Table 1)의 version 프로퍼티 허용 값 중 하나여야 한다(MUST).
Until Version:
프로퍼티가 폐기된 이후의 JSContact 버전. 따라서 그 이후 버전에서는 사용해서는 안 된다(MUST NOT). 값은 설정하지 않거나(MUST NOT be set) “JSContact Version” 레지스트리(Table 1)의 version 프로퍼티 허용 값 중 하나여야 한다(MUST).
Change Controller:
엔트리 정의 변경을 요청할 책임이 있는 사람 또는 엔터티(IETF 스트림의 RFC는 “IETF”).
Reference or Description:
프로퍼티가 정의된 위치의 간단한 설명 또는 RFC 번호와 절 참조. 이 프로퍼티가 도입되거나 갱신된 모든 RFC 문서에 대한 참조를 포함해야 한다. 예약 프로퍼티 이름은 참조 또는 설명을 생략할 수 있다(MAY).
3.5.2. JSContact Properties 레지스트리 초기 내용
아래 레지스트리 표의 프로퍼티 이름, 타입, 컨텍스트 및 참조는 표준 식별자와 직접 대조할 수 있도록 원문 표기를 유지한다.
The following table lists the initial “common” usage entries of the “JSContact Properties” registry. For all properties, the Since Version is “1.0”, the Until Version is not set, the Change Controller is “IETF”, and RFC section references are for RFC 9553.
Table 2: JSContact Properties with “common” Usage
| Property Name | Property Type | Property Context |
|---|---|---|
| @type | String | Address (Section 2.5.1.1), AddressComponent (Section 2.5.1.2), Anniversary (Section 2.8.1), Author (Section 2.8.3), Card (Section 2.1.1), Calendar (Section 2.4.1), CryptoKey (Section 2.6.1), Directory (Section 2.6.2), EmailAddress (Section 2.3.1), LanguagePref (Section 2.3.4), Link Section 2.6.3), Media (Section 2.6.4), Name (Section 2.2.1.1), NameComponent (Section 2.2.1.2), Nickname (Section 2.2.2), Note (Section 2.8.3), OnlineService (Section 2.3.2), Organization (Section 2.2.3), OrgUnit (Section 2.2.3), PartialDate (Section 2.8.1), PersonalInfo (Section 2.8.4), Phone (Section 2.3.3), Pronouns (Section 2.2.4), Relation (Section 2.1.8), SchedulingAddress (Section 2.4.2), SpeakToAs (Section 2.2.4), Timestamp (Section 2.8.1), Title (Section 2.2.5) |
| address | String | EmailAddress (Section 2.3.1) |
| addresses | Id[Address] | Card (Section 2.5.1.1) |
| anniversaries | Id[Anniversary] | Card (Section 2.8.1) |
| author | Author | Note (Section 2.8.3) |
| calendars | Id[Calendar] | Card (Section 2.4.1) |
| calendarScale | String | PartialDate (Section 2.8.1) |
| components | AddressComponent[] | Address (Section 2.5.1.1) |
| components | NameComponent[] | Name (Section 2.2.1.2) |
| contexts | String[Boolean] | Address (Section 2.5.1.1), Calendar (Section 2.4.1), CryptoKey (Section 2.6.1), Directory (Section 2.6.2), EmailAddress (Section 2.3.1), LanguagePref (Section 2.3.4), Link (Section 2.6.3), Media (Section 2.6.4), Nickname (Section 2.2.2), OnlineService (Section 2.3.2), Organization (Section 2.2.3), Phone (Section 2.3.3), Pronouns (Section 2.2.4), SchedulingAddress (Section 2.4.2). Also see Sections 1.4.4 and 1.5.1. |
| coordinates | String | Address (Section 2.5.1.1) |
| countryCode | String | Address (Section 2.5.1.1) |
| created | UTCDateTime | Card (Section 2.1.3), Note (Section 2.8.3) |
| date | PartialDate | Timestamp |
| day | UnsignedInt | PartialDate (Section 2.8.1) |
| defaultSeparator | String | Address (Section 2.5.1.1), Name (Section 2.2.1.1) |
| directories | Id[Directory] | Card (Section 2.6.2) |
| emails | Id[EmailAddress] | Card (Section 2.3.1) |
| features | String[Boolean] | Phone (Section 2.3.3) |
| full | String | Address (Section 2.5.1.1), Name (Section 2.2.1.1) |
| grammaticalGender | String | SpeakToAs (Section 2.2.4) |
| isOrdered | Boolean | Address (Section 2.5.1.1), Name (Section 2.2.1.1) |
| keywords | String[Boolean] | Card (Section 2.8.2) |
| kind | String | AddressComponent (Section 2.5.1.2), Anniversary (Section 2.8.1), Calendar (Section 2.4.1), Card (Section 2.1.4), CryptoKey (Section 2.6.1), Directory (Section 2.6.2), Link (Section 2.6.3), Media (Section 2.6.4), NameComponent (Section 2.2.1.2), PersonalInfo (Section 2.8.4), Title (Section 2.2.5) |
| label | String | Calendar (Section 2.4.1), CryptoKey (Section 2.6.1), Directory (Section 2.6.2), EmailAddress (Section 2.3.1), Link (Section 2.6.3), Media (Section 2.6.4), OnlineService (Section 2.3.2), PersonalInfo (Section 2.8.4), Phone (Section 2.3.3), SchedulingAddress (Section 2.4.2). Also see Sections 1.4.4 and 1.5.2. |
| language | String | Card (Section 2.1.5), LanguagePref (Section 2.3.4) |
| level | String | PersonalInfo (Section 2.8.4) |
| links | Id[Link] | Card (Section 2.6.3) |
| listAs | UnsignedInt | Directory (Section 2.6.2), PersonalInfo (Section 2.8.4) |
| localizations | String[PatchObject] | Card (Section 2.7.1) |
| media | Id[Media] | Card (Section 2.6.4) |
| mediaType | String | Calendar (Section 2.4.1), CryptoKey (Section 2.6.1), Directory (Section 2.6.2), Link (Section 2.6.3), Media (Section 2.6.4). Also see Section 1.4.4. |
| members | String[Boolean] | Card (Section 2.1.6) |
| month | UnsignedInt | PartialDate (Section 2.8.1) |
| name | Name | Card (Section 2.2.1.1) |
| name | String | Author (Section 2.8.3), Nickname (Section 2.2.2), Organization (Section 2.2.3), OrgUnit (Section 2.2.3), Title (Section 2.2.5) |
| nicknames | Id[Nickname] | Card (Section 2.2.2) |
| note | String | Note (Section 2.8.3) |
| notes | Id[Note] | Card (Section 2.8.3) |
| number | String | Phone (Section 2.3.3) |
| onlineServices | Id[OnlineService] | Card (Section 2.3.2) |
| organizationId | String | Title (Section 2.2.5) |
| organizations | Id[Organization] | Card (Section 2.2.3) |
| personalInfo | Id[PersonalInfo] | Card (Section 2.8.4) |
| phones | Id[Phone] | Card (Section 2.3.3) |
| phonetic | String | AddressComponent (Section 2.5.1.2), NameComponent (Section 2.2.1.2) |
| phoneticScript | String | Address (Section 2.5.1.1), Name (Section 2.2.1.1) |
| phoneticSystem | String | Address (2.5.1.1), Name (Section 2.2.1.1) |
| place | Address | Anniversary (Section 2.8.1) |
| pref | UnsignedInt | Address (Section 2.5.1.1), Calendar (Section 2.4.1), CryptoKey (Section 2.6.1), Directory (Section 2.6.2), EmailAddress (Section 2.3.1), LanguagePref (Section 2.3.4), Link (Section 2.6.3), Media (Section 2.6.4), Nickname (Section 2.2.2), OnlineService (Section 2.3.2), Phone (Section 2.3.3), Pronouns (Section 2.2.4), SchedulingAddress (Section 2.4.2). Also see Sections 1.4.4 and 1.5.3. |
| preferredLanguages | String[LanguagePref] | Card (Section 2.3.4) |
| prodId | String | Card (Section 2.1.7) |
| pronouns | Id[Pronouns] | SpeakToAs (Section 2.2.4) |
| relatedTo | String[Relation] | Card (Section 2.1.8) |
| relation | String[Boolean] | Relation (Section 2.1.8) |
| schedulingAddresses | Id[SchedulingAddress] | Card (Section 2.4.2) |
| service | String | OnlineService (Section 2.3.2) |
| sortAs | String[String] | Name (Section 2.2.1.1) |
| sortAs | String | Organization (Section 2.2.3), OrgUnit (Section 2.2.3) |
| speakToAs | SpeakToAs | Card (Section 2.2.4) |
| timeZone | String | Address (Section 2.5.1.1) |
| titles | Id[Title] | Card (Section 2.2.5) |
| uid | String | Card (Section 2.1.9) |
| units | OrgUnit[] | Organization (Section 2.2.3) |
| updated | UTCDateTime | Card (Section 2.1.10) |
| uri | String | Author (Section 2.8.3), Calendar (Section 2.4.1), CryptoKey (Section 2.6.1), Directory (Section 2.6.2), Link (Section 2.6.3), Media (Section 2.6.4), OnlineService (Section 2.3.2), SchedulingAddress (Section 2.4.2). Also see Section 1.4.4. |
| user | String | OnlineService (Section 2.3.2) |
| utc | UTCDateTime | Timestamp (Section 2.8.1) |
| value | String | AddressComponent (Section 2.5.1.2), NameComponent (Section 2.2.1.2), PersonalInfo (Section 2.8.4) |
| version | String | Card (Section 2.1.2) |
| year | UnsignedInt | PartialDate (Section 2.8.1) |
The following table lists the initial “reserved” usage entries of the “JSContact Properties” registry. For this property, the Change Controller is “IETF”, and the RFC section reference is for RFC 9553.
Table 3: JSContact Properties with “reserved” Usage
| Property Name | Property Type | Property Context | Intended Usage | Reference/Description |
|---|---|---|---|---|
| extra | not applicable | not applicable | reserved | Section 1.7.3.1 |
3.6. JSContact Types 레지스트리 생성
IANA는 “JSContact Types” 레지스트리를 생성했다. 이 레지스트리의 목적은 JSContact 타입 이름의 이름 충돌을 방지하고, JSContact 프로퍼티 값에 사용되는 모든 데이터 타입에 대한 완전한 참조를 제공하는 것이다.
레지스트리 엔트리는 “Type Name” 열을 기준으로 알파벳 오름차순 정렬한다. 동일한 엔트리의 순서는 임의이다.
새 타입의 레지스트리 절차는 Section 3.3에 설명되어 있다.
3.6.1. JSContact Types 레지스트리 템플릿
Type Name:
타입의 이름.
Intended Usage:
“common”, “reserved”, “obsolete” 중 하나일 수 있다.
Since Version:
이 타입 정의가 기반하는 JSContact 버전. “JSContact Version” 레지스트리(Table 1)에서 version 프로퍼티에 허용된 값 중 하나여야 한다(MUST).
Until Version:
타입 정의가 폐기된 이후의 JSContact 버전. 따라서 더 이후 버전에서는 사용해서는 안 된다(MUST NOT). Until Version 값은 설정하지 않거나 “JSContact Version” 레지스트리(Table 1)에서 version 프로퍼티에 허용된 값 중 하나여야 한다(MUST).
Change Controller:
엔트리 정의 변경 요청을 담당하는 사람 또는 엔터티(IETF 스트림 RFC는 “IETF”).
Reference or Description:
타입이 정의된 위치에 대한 간단한 설명 또는 RFC 번호와 절 참조. 예약된 타입 이름은 참조 또는 설명을 생략할 수 있다(MAY).
3.6.2. JSContact Types 레지스트리 초기 내용
아래 표는 “JSContact Types” 레지스트리의 초기 “common” usage 엔트리를 나열한다. 모든 타입에서 Since Version은 “1.0”, Until Version은 설정되지 않으며 Change Controller는 “IETF”이고 RFC 절 참조는 RFC 9553을 가리킨다.
타입 이름과 참조는 표준 식별자와 직접 대조할 수 있도록 원문 표기를 유지한다.
3.6.2. Initial Contents of the JSContact Types Registry
The following table lists the initial “common” usage entries in the “JSContact Types” registry. For all of these types, the Since Version is “1.0”, the Until Version is not set, the Change Controller is “IETF”, and RFC section references are for RFC 9553.
Table 4: JSContact Types with “common” Usage
| Type Name | Reference/Description |
|---|---|
| Address | Section 2.5.1.1 |
| AddressComponent | Section 2.5.1.2 |
| Anniversary | Section 2.8.1 |
| Author | Section 2.8.3 |
| Boolean | Section 1.3.2 |
| Calendar | Section 2.4.1 |
| Card | Section 2 |
| CryptoKey | Section 2.6.1 |
| Directory | Section 2.6.2 |
| EmailAddress | Section 2.3.1 |
| Id | Section 1.4.1 |
| Int | Section 1.4.2 |
| LanguagePref | Section 2.3.4 |
| Link | Section 2.6.3 |
| Media | Section 2.6.4 |
| Name | Section 2.2.1.1 |
| NameComponent | Section 2.2.1.2 |
| Nickname | Section 2.2.2 |
| Note | Section 2.8.3 |
| Number | Section 1.3.2 |
| OnlineService | Section 2.3.2 |
| Organization | Section 2.2.3 |
| OrgUnit | Section 2.2.3 |
| PartialDate | Section 2.8.1 |
| PatchObject | Section 1.4.3 |
| PersonalInfo | Section 2.8.4 |
| Phone | Section 2.3.3 |
| Pronouns | Section 2.2.4 |
| Relation | Section 2.1.8 |
| SchedulingAddress | Section 2.4.2 |
| SpeakToAs | Section 2.2.4 |
| String | Section 1.3.2 |
| Timestamp | Section 2.8.1 |
| Title | Section 2.2.5 |
| UnsignedInt | Section 1.4.2 |
| UTCDateTime | Section 1.4.5 |
The following table lists the initial “reserved” usage entry of the “JSContact Types” registry. For this type, the version is “1.0”, the Change Controller is “IETF”, and the RFC section reference is for RFC 9553.
Table 5: JSContact Types with “reserved” Usage
| Type Name | Reference/Description |
|---|---|
| Resource | Section 1.4.4 |
3.7. JSContact Enum Values 레지스트리 생성
IANA는 “JSContact Enum Values” 레지스트리를 생성했다. 이 레지스트리의 목적은 열거 가능한 값을 갖는 JSContact 프로퍼티의 의미를 상호운용 가능한 방식으로 확장할 수 있게 하는 것이다. 이러한 각 프로퍼티에는 허용 값의 하위 레지스트리가 존재한다.
레지스트리 엔트리는 먼저 “Property Name”, 다음 “Property Context”, 그 다음 “Since Version” 열을 기준으로 알파벳 오름차순 정렬한다. enum 값도 알파벳 오름차순으로 정렬한다. 동일한 엔트리의 순서는 임의이다.
새 enum 값 또는 새 열거형 프로퍼티 추가를 위한 레지스트리 절차는 Section 3.3에 설명되어 있다.
3.7.1. JSContact Enum Values 레지스트리 프로퍼티 템플릿
이 템플릿은 새로운 열거형 프로퍼티의 하위 레지스트리를 “JSContact Enum Values” 레지스트리에 추가하기 위한 것이다.
Property Name:
이 값들을 사용할 수 있는 프로퍼티의 이름. “JSContact Properties” 레지스트리에 등록되어 있어야 한다(MUST).
Context:
“JSContact Properties” 레지스트리에 등록된, 해당 프로퍼티가 나타날 수 있는 허용 객체 타입 목록. 서로 다른 컨텍스트에 같은 이름의 서로 다른 프로퍼티가 있을 때 이를 구분한다.
Since Version:
enum 값 정의가 기반하는 JSContact 버전. “JSContact Version” 레지스트리(Table 1)에서 version 프로퍼티에 허용된 값 중 하나여야 한다(MUST).
Until Version:
enum 값 정의가 폐기된 이후의 JSContact 버전. 따라서 이후 버전에서는 해당 enum 값 정의를 사용해서는 안 된다(MUST NOT). Until Version은 설정하지 않거나 “JSContact Version” 레지스트리(Table 1)에서 version 프로퍼티에 허용된 값 중 하나여야 한다(MUST).
Change Controller:
엔트리 정의 변경 요청을 담당하는 사람 또는 엔터티(IETF 스트림 RFC는 “IETF”).
Reference or Description:
값의 의미를 설명하는 간단한 설명 또는 RFC 번호와 절 참조.
초기 내용은 Section 3.7.2에 정의된 템플릿을 사용하는 enum의 초기 정의 값 목록이라는 점에 유의한다. 이 property name/context 튜플에 대해 이러한 값을 가진 하위 레지스트리가 생성된다.
3.7.2. JSContact Enum Values 레지스트리 값 템플릿
이 템플릿은 “JSContact Enum Values” 레지스트리의 하위 레지스트리에 새 enum 값을 추가하기 위한 것이다.
Enum Value:
enum의 값을 그대로 기입한다.
Since Version:
enum 값 정의가 기반하는 JSContact 버전. “JSContact Version” 레지스트리(Table 1)에서 version 프로퍼티에 허용된 값 중 하나여야 한다(MUST).
Until Version:
enum 값이 폐기된 이후의 JSContact 버전. 따라서 이후 버전에서는 enum 값을 사용해서는 안 된다(MUST NOT). Until Version은 설정하지 않거나 “JSContact Version” 레지스트리(Table 1)에서 version 프로퍼티에 허용된 값 중 하나여야 한다(MUST).
Change Controller:
엔트리 정의 변경 요청을 담당하는 사람 또는 엔터티(IETF 스트림 RFC는 “IETF”).
Reference or Description:
값의 의미에 대한 간단한 설명 또는 RFC 번호와 절 참조.
3.7.3. JSContact Enum Values 레지스트리 초기 내용
이 절에서 생성되는 각 하위 레지스트리의 모든 엔트리에서 Since Version은 “1.0”, Until Version은 설정되지 않으며 Change Controller는 “IETF”이고 RFC 절 참조는 RFC 9553을 가리킨다.
열거형 프로퍼티명·컨텍스트·값 및 레지스트리 표는 구현 시 정확한 원문 식별자 확인을 위해 원문 표기를 유지한다.
3.7.3. Initial Contents of the JSContact Enum Values Registry
For all entries in each subregistry created in this section, the Since Version is “1.0”, the Until Version is not set, the Change Controller is “IETF”, and RFC section references are for RFC 9553.
Property Name:
contexts
Context:
Address
Initial Contents:
Table 6: JSContact Enum Values for contexts (Context: Address)
| Enum Value | Reference/Description |
|---|---|
| billing | Section 2.5.1.1 |
| delivery | Section 2.5.1.1 |
| private | Section 1.5.1 |
| work | Section 1.5.1 |
Property Name:
contexts
Context:
Calendar, CryptoKey, Directory, EmailAddress, LanguagePref, Link, Media, Nickname, OnlineService, Organization, Phone, Pronouns, SchedulingAddress
Initial Contents:
Table 7: JSContact Enum Values for contexts (Context: Calendar, CryptoKey, Directory, EmailAddress, LanguagePref, Link, Media, Nickname, OnlineService, Organization, Phone, Pronouns, SchedulingAddress)
| Enum Value | Reference/Description |
|---|---|
| private | Section 1.5.1 |
| work | Section 1.5.1 |
Property Name:
features
Context:
Phone
Initial Contents:
Table 8: JSContact Enum Values for features (Context: Phone)
| Enum Value | Reference/Description |
|---|---|
| fax | Section 2.3.3 |
| main-number | Section 2.3.3 |
| mobile | Section 2.3.3 |
| pager | Section 2.3.3 |
| text | Section 2.3.3 |
| textphone | Section 2.3.3 |
| video | Section 2.3.3 |
| voice | Section 2.3.3 |
Property Name:
grammaticalGender
Context:
SpeakToAs
Initial Contents:
Table 9: JSContact Enum Values for grammaticalGender (Context: SpeakToAs)
| Enum Value | Reference/Description |
|---|---|
| animate | Section 2.2.4 |
| common | Section 2.2.4 |
| feminine | Section 2.2.4 |
| inanimate | Section 2.2.4 |
| masculine | Section 2.2.4 |
| neuter | Section 2.2.4 |
Property Name:
kind
Context:
AddressComponent
Initial Contents:
Table 10: JSContact Enum Values for kind (Context: AddressComponent)
| Enum Value | Reference/Description |
|---|---|
| apartment | Section 2.5.1.2 |
| block | Section 2.5.1.2 |
| building | Section 2.5.1.2 |
| country | Section 2.5.1.2 |
| direction | Section 2.5.1.2 |
| district | Section 2.5.1.2 |
| floor | Section 2.5.1.2 |
| landmark | Section 2.5.1.2 |
| locality | Section 2.5.1.2 |
| name | Section 2.5.1.2 |
| number | Section 2.5.1.2 |
| postcode | Section 2.5.1.2 |
| postOfficeBox | Section 2.5.1.2 |
| region | Section 2.5.1.2 |
| room | Section 2.5.1.2 |
| separator | Section 2.5.1.2 |
| subdistrict | Section 2.5.1.2 |
Property Name:
kind
Context:
Anniversary
Initial Contents:
Table 11: JSContact Enum Values for kind (Context: Anniversary)
| Enum Value | Reference/Description |
|---|---|
| birth | Section 2.8.1 |
| death | Section 2.8.1 |
| wedding | Section 2.8.1 |
Property Name:
kind
Context:
Calendar
Initial Contents:
Table 12: JSContact Enum Values for kind (Context: Calendar)
| Enum Value | Reference/Description |
|---|---|
| calendar | Section 2.4.1 |
| freeBusy | Section 2.4.1 |
Property Name:
kind
Context:
Card
Initial Contents:
Table 13: JSContact Enum Values for kind (Context: Card)
| Enum Value | Reference/Description |
|---|---|
| application | Section 2.1.4 |
| device | Section 2.1.4 |
| group | Section 2.1.4 |
| individual | Section 2.1.4 |
| location | Section 2.1.4 |
| org | Section 2.1.4 |
Property Name:
kind
Context:
Directory
Initial Contents:
Table 14: JSContact Enum Values for kind (Context: Directory)
| Enum Value | Reference/Description |
|---|---|
| directory | Section 2.6.2 |
| entry | Section 2.6.2 |
Property Name:
kind
Context:
Link
Initial Contents:
Table 15: JSContact Enum Values for kind (Context: Link)
| Enum Value | Reference/Description |
|---|---|
| contact | Section 2.6.3 |
Property Name:
kind
Context:
Media
Initial Contents:
Table 16: JSContact Enum Values for kind (Context: Media)
| Enum Value | Reference/Description |
|---|---|
| logo | Section 2.6.4 |
| photo | Section 2.6.4 |
| sound | Section 2.6.4 |
Property Name:
kind
Context:
NameComponent
Initial Contents:
Table 17: JSContact Enum Values for kind (Context: NameComponent)
| Enum Value | Reference/Description |
|---|---|
| credential | Section 2.2.1.2 |
| generation | Section 2.2.1.2 |
| given | Section 2.2.1.2 |
| given2 | Section 2.2.1.2 |
| separator | Section 2.2.1.2 |
| surname | Section 2.2.1.2 |
| surname2 | Section 2.2.1.2 |
| title | Section 2.2.1.2 |
Property Name:
kind
Context:
PersonalInfo
Initial Contents:
Table 18: JSContact Enum Values for kind (Context: PersonalInfo)
| Enum Value | Reference/Description |
|---|---|
| expertise | Section 2.8.4 |
| hobby | Section 2.8.4 |
| interest | Section 2.8.4 |
Property Name:
kind
Context:
Title
Initial Contents:
Table 19: JSContact Enum Values for kind (Context: Title)
| Enum Value | Reference/Description |
|---|---|
| role | Section 2.2.5 |
| title | Section 2.2.5 |
Property Name:
level
Context:
PersonalInfo
Initial Contents:
Table 20: JSContact Enum Values for level (Context: PersonalInfo)
| Enum Value | Reference/Description |
|---|---|
| high | Section 2.8.4 |
| low | Section 2.8.4 |
| medium | Section 2.8.4 |
Property Name:
phoneticSystem
Context:
Address, Name
Initial Contents:
Table 21: JSContact Enum Values for phoneticSystem (Context: Address, Name)
| Enum Value | Reference/Description |
|---|---|
| ipa | Section 1.5.4 |
| jyut | Section 1.5.4 |
| piny | Section 1.5.4 |
Property Name:
relation
Context:
Relation
Initial Contents:
Table 22: JSContact Enum Values for relation (Context: Relation)
| Enum Value | Reference/Description |
|---|---|
| acquaintance | Section 2.1.8 |
| agent | Section 2.1.8 |
| child | Section 2.1.8 |
| colleague | Section 2.1.8 |
| contact | Section 2.1.8 |
| co-resident | Section 2.1.8 |
| co-worker | Section 2.1.8 |
| crush | Section 2.1.8 |
| date | Section 2.1.8 |
| emergency | Section 2.1.8 |
| friend | Section 2.1.8 |
| kin | Section 2.1.8 |
| me | Section 2.1.8 |
| met | Section 2.1.8 |
| muse | Section 2.1.8 |
| neighbor | Section 2.1.8 |
| parent | Section 2.1.8 |
| sibling | Section 2.1.8 |
| spouse | Section 2.1.8 |
| sweetheart | Section 2.1.8 |
4. 보안 고려사항
연락처 정보는 개인정보 보호 측면에서 매우 민감하다. 사용자의 신원, 위치, 자격 정보, 고용 상태, 관심사와 취미, 사회적 네트워크를 드러낼 수 있다. 도청, 재전송(replay), 메시지 삽입, 삭제, 수정, on-path 공격 같은 위협으로부터 보호하기 위해 전송과 저장을 신중하게 처리해야 한다.
저장되고 전송되는 데이터는 현실 세계에 영향을 미치는 시스템에서 사용될 수 있다. 예를 들어 악의적인 행위자가 다른 사람의 이름을 사용하면서 자신의 연락처 정보를 삽입한 JSContact 데이터를 제공해, 자신이 알지 못하는 피해자를 사칭할 수 있다. 그러한 시스템은 시스템이 전복되는 것을 방지하고 변경이 권한 있는 엔터티에서 왔음을 보장하기 위해 수신하는 모든 데이터를 신중하게 인증해야 한다.
이 문서는 데이터 형식만 정의한다. 이러한 고려사항은 주로 해당 파일을 저장하고 전송하는 API 또는 방법의 책임이다.
4.1. JSON 파싱
JSON을 데이터 교환 형식으로 사용할 때에는 [RFC8259]의 보안 고려사항이 적용된다.
모든 직렬화 형식과 마찬가지로 파서는 제공된 데이터의 구문을 철저하게 검사해야 한다. JSON은 여러 타입과 구조에 여는 괄호와 닫는 괄호를 사용하므로, 대응하는 닫는 괄호를 찾는 동안 제공된 데이터의 끝에 도달할 수 있다. 이는 오류 조건이며 구현체는 제공된 데이터의 끝에서 스캔을 중단해야 한다.
JSON은 문자열 안의 특수 문자를 인코딩하기 위해 일부 escape sequence를 사용하는 문자열 인코딩도 사용한다. 이러한 escape sequence를 처리할 때는 특수 처리를 시작하기 전에 시퀀스가 완전한지 확인해야 한다. 특히 escape sequence가 다른 이스케이프되지 않은 특수 문자와 인접하거나, 앞 단락처럼 데이터 끝과 인접한 경우 주의해야 한다.
JSON을 비텍스트 구조화 데이터 형식으로 파싱하는 경우 구현체는 JSON 문자열 요소를 저장할 공간을 할당해야 할 수 있다. JSON은 명시적인 문자열 길이를 사용하지 않으므로 리소스 고갈에 따른 서비스 거부 위험은 작지만, 신뢰할 수 없는 데이터가 과도한 메모리 할당을 유발하지 않도록 구현체는 각 맥락에서 허용할 할당 크기에 제한을 둘 수 있다.
4.2. URI 값
여러 JSContact 프로퍼티는 URI를 값으로 포함하며 이러한 프로퍼티를 처리할 때는 추가적인 주의가 필요하다. [RFC3986]의 Section 7은 URI와 관련된 보안 위험을 논의한다.
원격 리소스를 가져오는 작업에는 본질적인 위험이 있다. 연결은 잘 알려진 포트에서 허용된 프로토콜(일반적으로 기본 포트의 HTTP/HTTPS)만 사용하도록 허용해야 한다. URL은 외부에서 해석되어야 하며 내부 리소스에 접근할 수 있게 해서는 안 된다. 외부 소스에 연결하면 IP 정보(따라서 종종 위치 정보)도 노출된다.
악의적으로 구성된 JSContact 객체는 매우 많은 URI를 포함할 수 있다. 구독자가 많은 공개 주소록의 경우 그러한 객체가 광범위하게 배포될 수 있다. 구현체는 연결된 리소스의 자동 가져오기를 제한하여 서비스 거부 공격의 증폭 벡터가 될 위험을 줄이는 데 주의하는 것이 좋다.
5. 참고문헌
5.1. 규범적 참고문헌
서지정보의 제목·저자·RFC 번호·링크는 원문과의 정확한 대조를 위해 원문 표기를 유지한다.
[IANA-TZ]
IANA, “Time Zone Database”, <https://www.iana.org/time-zones>.
[IANA-vCard]
IANA, “vCard Elements”, <https://www.iana.org/assignments/vcard-elements>.
[ISO.3166-1]
International Organization for Standardization, “Codes for the representation of names of countries and their subdivisions — Part 1: Country codes”, ISO 3166-1:2020, August 2020.
[RFC1034]
Mockapetris, P., “Domain names – concepts and facilities”, STD 13, RFC 1034, DOI 10.17487/RFC1034, November 1987, <https://www.rfc-editor.org/info/rfc1034>.
[RFC1035]
Mockapetris, P., “Domain names – implementation and specification”, STD 13, RFC 1035, DOI 10.17487/RFC1035, November 1987, <https://www.rfc-editor.org/info/rfc1035>.
[RFC2046]
Freed, N. and N. Borenstein, “Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types”, RFC 2046, DOI 10.17487/RFC2046, November 1996, <https://www.rfc-editor.org/info/rfc2046>.
[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
[RFC2426]
Dawson, F. and T. Howes, “vCard MIME Directory Profile”, RFC 2426, DOI 10.17487/RFC2426, September 1998, <https://www.rfc-editor.org/info/rfc2426>.
[RFC3339]
Klyne, G. and C. Newman, “Date and Time on the Internet: Timestamps”, RFC 3339, DOI 10.17487/RFC3339, July 2002, <https://www.rfc-editor.org/info/rfc3339>.
[RFC4648]
Josefsson, S., “The Base16, Base32, and Base64 Data Encodings”, RFC 4648, DOI 10.17487/RFC4648, October 2006, <https://www.rfc-editor.org/info/rfc4648>.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.
[RFC5322]
Resnick, P., Ed., “Internet Message Format”, RFC 5322, DOI 10.17487/RFC5322, October 2008, <https://www.rfc-editor.org/info/rfc5322>.
[RFC5646]
Phillips, A., Ed. and M. Davis, Ed., “Tags for Identifying Languages”, BCP 47, RFC 5646, DOI 10.17487/RFC5646, September 2009, <https://www.rfc-editor.org/info/rfc5646>.
[RFC5870]
Mayrhofer, A. and C. Spanring, “A Uniform Resource Identifier for Geographic Locations (‘geo’ URI)”, RFC 5870, DOI 10.17487/RFC5870, June 2010, <https://www.rfc-editor.org/info/rfc5870>.
[RFC6350]
Perreault, S., “vCard Format Specification”, RFC 6350, DOI 10.17487/RFC6350, August 2011, <https://www.rfc-editor.org/info/rfc6350>.
[RFC6901]
Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., “JavaScript Object Notation (JSON) Pointer”, RFC 6901, DOI 10.17487/RFC6901, April 2013, <https://www.rfc-editor.org/info/rfc6901>.
[RFC7493]
Bray, T., Ed., “The I-JSON Message Format”, RFC 7493, DOI 10.17487/RFC7493, March 2015, <https://www.rfc-editor.org/info/rfc7493>.
[RFC7529]
Daboo, C. and G. Yakushev, “Non-Gregorian Recurrence Rules in the Internet Calendaring and Scheduling Core Object Specification (iCalendar)”, RFC 7529, DOI 10.17487/RFC7529, May 2015, <https://www.rfc-editor.org/info/rfc7529>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.
[RFC8141]
Saint-Andre, P. and J. Klensin, “Uniform Resource Names (URNs)”, RFC 8141, DOI 10.17487/RFC8141, April 2017, <https://www.rfc-editor.org/info/rfc8141>.
[RFC8174]
Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259]
Bray, T., Ed., “The JavaScript Object Notation (JSON) Data Interchange Format”, STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, <https://www.rfc-editor.org/info/rfc8259>.
5.2. 정보 제공용 참고문헌
서지정보의 제목·저자·RFC 번호·링크는 원문과의 정확한 대조를 위해 원문 표기를 유지한다.
[IPA]
IPA, “International Phonetic Alphabet”, <https://www.internationalphoneticalphabet.org/>.
[RFC3261]
Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, “SIP: Session Initiation Protocol”, RFC 3261, DOI 10.17487/RFC3261, June 2002, <https://www.rfc-editor.org/info/rfc3261>.
[RFC3966]
Schulzrinne, H., “The tel URI for Telephone Numbers”, RFC 3966, DOI 10.17487/RFC3966, December 2004, <https://www.rfc-editor.org/info/rfc3966>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>.
[RFC3987]
Duerst, M. and M. Suignard, “Internationalized Resource Identifiers (IRIs)”, RFC 3987, DOI 10.17487/RFC3987, January 2005, <https://www.rfc-editor.org/info/rfc3987>.
[RFC6351]
Perreault, S., “xCard: vCard XML Representation”, RFC 6351, DOI 10.17487/RFC6351, August 2011, <https://www.rfc-editor.org/info/rfc6351>.
[RFC6473]
Saint-Andre, P., “vCard KIND:application”, RFC 6473, DOI 10.17487/RFC6473, December 2011, <https://www.rfc-editor.org/info/rfc6473>.
[RFC6474]
Li, K. and B. Leiba, “vCard Format Extensions: Place of Birth, Place and Date of Death”, RFC 6474, DOI 10.17487/RFC6474, December 2011, <https://www.rfc-editor.org/info/rfc6474>.
[RFC6715]
Cauchie, D., Leiba, B., and K. Li, “vCard Format Extensions: Representing vCard Extensions Defined by the Open Mobile Alliance (OMA) Converged Address Book (CAB) Group”, RFC 6715, DOI 10.17487/RFC6715, August 2012, <https://www.rfc-editor.org/info/rfc6715>.
[RFC6869]
Salgueiro, G., Clarke, J., and P. Saint-Andre, “vCard KIND:device”, RFC 6869, DOI 10.17487/RFC6869, February 2013, <https://www.rfc-editor.org/info/rfc6869>.
[RFC7095]
Kewisch, P., “jCard: The JSON Format for vCard”, RFC 7095, DOI 10.17487/RFC7095, January 2014, <https://www.rfc-editor.org/info/rfc7095>.
[RFC8605]
Hollenbeck, S. and R. Carney, “vCard Format Extensions: ICANN Extensions for the Registration Data Access Protocol (RDAP)”, RFC 8605, DOI 10.17487/RFC8605, May 2019, <https://www.rfc-editor.org/info/rfc8605>.
[RFC9499]
Hoffman, P. and K. Fujiwara, “DNS Terminology”, BCP 219, RFC 9499, DOI 10.17487/RFC9499, March 2024, <https://www.rfc-editor.org/info/rfc9499>.
[RFC9554]
Stepanek, R. and M. Loffredo, “vCard Format Extensions for JSContact”, RFC 9554, DOI 10.17487/RFC9554, May 2024, <https://www.rfc-editor.org/info/rfc9554>.
[RFC9555]
Stepanek, R. and M. Loffredo, “JSContact: Converting from and to vCard”, RFC 9555, DOI 10.17487/RFC9555, May 2024, <https://www.rfc-editor.org/info/rfc9555>.
[RFC9562]
Davis, K., Peabody, B., and P. Leach, “Universally Unique IDentifiers (UUIDs)”, RFC 9562, DOI 10.17487/RFC9562, May 2024, <https://www.rfc-editor.org/info/rfc9562>.
[UBiDi]
The Unicode Consortium, “Unicode Standard Annex #9: Unicode Bidirectional Algorithm”, Revision 48, Unicode 15.1.0, August 2023, <https://www.unicode.org/reports/tr9/>.
[WHATWG-URL]
WHATWG, “URL Living Standard”, January 2024, <https://url.spec.whatwg.org>.
저자 주소
Robert Stepanek
Fastmail
PO Box 234
Collins St. West
Melbourne VIC 8007
Australia
Email: rsto@fastmailteam.com
Mario Loffredo
IIT-CNR
Via Moruzzi, 1
56124 Pisa
Italy
Email: mario.loffredo@iit.cnr.it

답글 남기기