directory.openapi.yml 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. .references:
  2. work-servers: &work-servers
  3. - url: https://ds-apip-work.threema.ch
  4. description: Production server
  5. - url: https://ds-apip-work.test.threema.ch
  6. description: Sandbox server
  7. base64: &base64
  8. type: string
  9. format: byte
  10. u64: &u64
  11. type: integer
  12. minimum: 0
  13. maximum: 18446744073709551615
  14. identity: &identity
  15. description: A Threema ID.
  16. type: string
  17. minLength: 8
  18. maxLength: 8
  19. pattern: ^([0-9A-Z\\*][0-9A-Z]{7}|\\*)$
  20. example: ECHOECHO
  21. public-key: &public-key
  22. <<: *base64
  23. description: Public Key (32 bytes, base64) associated to a Threema ID.
  24. example: ZWNob2VjaG9lY2hvZWNob2VjaG9lY2hvZWNob2VjaG8=
  25. app-version: &app-version
  26. description: |-
  27. App version. This is the CSP `client-info` but with the following special postfix:
  28. 1. If at least one Threema-MDM parameter and at least one external MDM parameter is active, append `;me`
  29. 2. If at least one Threema-MDM parameter is active, append `;m`
  30. 3. If at least one external MDM parameter is active, append `;e`
  31. 4. If no MDM parameter is active, don't append. (A lone `;` is also acceptable.)
  32. type: string
  33. minLength: 1
  34. example: 1.2.3;Q;de/DE;...
  35. work-username: &work-username
  36. description: Work license username.
  37. type: string
  38. minLength: 1
  39. example: echoecho@threema.ch
  40. work-password: &work-password
  41. description: Work license password.
  42. type: string
  43. minLength: 1
  44. example: super-secret-password
  45. work-nickname: &work-nickname
  46. description: |-
  47. User's nickname sourced from the MDM parameter `th_nickname`. Empty is
  48. equivalent to unset.
  49. type: string
  50. example: personal-🦜
  51. work-first-name: &work-first-name
  52. description: |-
  53. User's first name sourced from the MDM parameter `th_firstname`. Empty is
  54. equivalent to unset.
  55. type: string
  56. example: Aria
  57. work-last-name: &work-last-name
  58. description: |-
  59. User's last name sourced from the MDM parameter `th_lastname`. Empty is
  60. equivalent to unset.
  61. type: string
  62. example: Reverb
  63. work-user-identifier: &work-user-identifier
  64. description: |-
  65. Custom unique identifier of the user (e.g. employee number), sourced from
  66. the MDM parameter `th_csi`. Also known as _Customer Specific Identifier_.
  67. Empty is equivalent to unset.
  68. type: string
  69. work-user-categories-delimited: &work-user-categories-delimited
  70. description: |-
  71. Custom categories of the user (e.g. building name, room number), sourced
  72. from the MDM parameter `th_category`. Empty is equivalent to unset.
  73. Note: For compatibility with the app configuration parameter
  74. `th_category`, this is the delimited variant with the category name
  75. separated by the category delimiter (`,` by default).
  76. type: string
  77. example: Building 1, Room 337
  78. work-user-category-id: &work-user-category-id
  79. description: A custom category ID.
  80. type: string
  81. minLength: 1
  82. example: 'jNekOWhQ8B'
  83. work-user-category-ids: &work-user-category-ids
  84. description: |-
  85. Custom category IDs of the user (e.g. mapping to the building name, room
  86. number), chosen by the Work subscription administrator.
  87. type: array
  88. items: *work-user-category-id
  89. example:
  90. - '1'
  91. - 'jNekOWhQ8B'
  92. work-contacts-match: &work-contacts-match
  93. type: array
  94. items: *identity
  95. example:
  96. - ECHOECHO
  97. - '*SUPPORT'
  98. work-contact: &work-contact
  99. type: object
  100. required:
  101. - id
  102. - pk
  103. properties:
  104. id: *identity
  105. pk: *public-key
  106. first:
  107. <<: *work-first-name
  108. type:
  109. - string
  110. - 'null'
  111. last:
  112. <<: *work-last-name
  113. type:
  114. - string
  115. - 'null'
  116. work-organisation: &work-organisation
  117. type: object
  118. required:
  119. - name
  120. properties:
  121. name:
  122. description: |-
  123. Optional name of the organisation, translated by the `Accept-Language`
  124. header (if provided).
  125. type:
  126. - string
  127. - 'null'
  128. work-directory-page-index: &work-directory-page-index
  129. description: Page index.
  130. type: integer
  131. minimum: 0
  132. work-directory-sort: &work-directory-sort
  133. type: object
  134. properties:
  135. by:
  136. description: The sort key applied to the resulting contacts.
  137. type: string
  138. default: firstName
  139. enum:
  140. - firstName
  141. - lastName
  142. asc:
  143. description: |-
  144. Sort contacts ascending by `by` if `true`, sort descending if `false`.
  145. type: boolean
  146. default: true
  147. auth-challenge-request: &auth-challenge-request
  148. description: Authentication required.
  149. type: object
  150. required:
  151. - token
  152. - tokenRespKeyPub
  153. properties:
  154. token:
  155. <<: *base64
  156. description: An arbitrary challenge token (base64) to be _signed_.
  157. tokenRespKeyPub:
  158. <<: *base64
  159. description: |-
  160. The ephemeral public key (EPK, 32 bytes, base64) to derive a shared
  161. secret for solving the challenge.
  162. auth-challenge-response: &auth-challenge-response
  163. type: object
  164. required:
  165. - token
  166. - response
  167. properties:
  168. token:
  169. <<: *base64
  170. description: The token of the challenge request (base64).
  171. response:
  172. <<: *base64
  173. description: |-
  174. The token of the challenge request, _signed_ in the following way:
  175. ```text
  176. base64(
  177. BLAKE2b(
  178. key=BLAKE2b(
  179. key=X25519HSalsa20(CK.secret, EPK.public),
  180. salt='dir',
  181. personal='3ma-csp',
  182. ),
  183. input=<token>
  184. )
  185. )
  186. ```
  187. update-work-data-request: &update-work-data-request
  188. type: object
  189. required:
  190. - identity
  191. - licenseUsername
  192. - licensePassword
  193. - version
  194. properties:
  195. identity: *identity
  196. licenseUsername: *work-username
  197. licensePassword: *work-password
  198. version: *app-version
  199. publicNickname: *work-nickname
  200. firstName: *work-first-name
  201. lastName: *work-last-name
  202. csi: *work-user-identifier
  203. category: *work-user-categories-delimited
  204. update-work-data-response:
  205. ok: &update-work-data-response-ok
  206. description: Work data updated successfully.
  207. type: object
  208. required:
  209. - success
  210. properties:
  211. success:
  212. type: boolean
  213. const: true
  214. error: &update-work-data-response-error
  215. description: Updating Work data failed.
  216. type: object
  217. required:
  218. - success
  219. properties:
  220. success:
  221. type: boolean
  222. const: false
  223. error:
  224. type: string
  225. example:
  226. sucess: false
  227. error: 'Missing parameters'
  228. work-auth: &work-auth
  229. type: object
  230. required:
  231. - username
  232. - password
  233. properties:
  234. username: *work-username
  235. password: *work-password
  236. sync-work-data-request: &sync-work-data-request
  237. type: object
  238. required:
  239. - contacts
  240. properties:
  241. contacts:
  242. <<: *work-contacts-match
  243. description: |-
  244. A list of all existing contacts of the user to match against the Work
  245. subscription.
  246. Note: This is necessary to determine whether a contact is part of the
  247. user's Work subscription and, in that case, get additional
  248. information.
  249. Note 2: Explicitly providing all of the user's contacts also prevents
  250. having to configure **all** Work contacts of the same subscription.
  251. sync-work-data-response: &sync-work-data-response
  252. type: object
  253. required:
  254. - checkInterval
  255. - org
  256. - logo
  257. - support
  258. - directory
  259. - mdm
  260. - contacts
  261. properties:
  262. checkInterval:
  263. <<: *u64
  264. description: |-
  265. Target amount of seconds until a subsequent Work sync should be
  266. initiated.
  267. org: *work-organisation
  268. logo:
  269. description: Logo to be displayed in the app.
  270. type: object
  271. required:
  272. - light
  273. - dark
  274. properties:
  275. light: &work-logo-url
  276. description: |-
  277. Optional URL to a logo to be displayed in the app. The logo must
  278. be provided in PNG format.
  279. type:
  280. - string
  281. - 'null'
  282. dark: *work-logo-url
  283. support:
  284. description: Optional custom in-app support base URL.
  285. type:
  286. - string
  287. - 'null'
  288. directory:
  289. oneOf:
  290. - description: Disabled Work directory.
  291. type: object
  292. required:
  293. - enabled
  294. properties:
  295. enabled:
  296. type: boolean
  297. const: false
  298. - description: Enabled Work directory.
  299. type: object
  300. required:
  301. - enabled
  302. - cat
  303. properties:
  304. enabled:
  305. type: boolean
  306. const: true
  307. cat:
  308. description: |-
  309. Map of contact category IDs to their respective (display) name.
  310. type: object
  311. additionalProperties: *work-user-category-id
  312. mdm:
  313. description: App configuration to be applied.
  314. type: object
  315. required:
  316. - override
  317. - params
  318. properties:
  319. override:
  320. description: |-
  321. Whether the app configuration parameters provided here take
  322. precedence over the the externally configured MDM parameters.
  323. type: boolean
  324. params:
  325. description: |-
  326. A key/value map of app configuration / MDM parameters as defined
  327. by the protocol.
  328. type: object
  329. additionalProperties:
  330. oneOf:
  331. - type: string
  332. - *u64
  333. - type: boolean
  334. contacts:
  335. description: |-
  336. A list of contacts from the same Work subscription to be configured
  337. on the user's device.
  338. type: array
  339. items:
  340. <<: *work-contact
  341. description: A configured Work contact.
  342. work-contacts-request: &work-contacts-request
  343. type: object
  344. required:
  345. - contacts
  346. properties:
  347. contacts:
  348. <<: *work-contacts-match
  349. description: |-
  350. A list of contacts (Threema IDs) to get additional Work properties for.
  351. Note: This is necessary to determine whether a contact is part of the
  352. user's Work subscription and, in that case, get additional
  353. information.
  354. work-contacts-response: &work-contacts-response
  355. type: object
  356. required:
  357. - contacts
  358. properties:
  359. contacts:
  360. description: |-
  361. A subset of the provided contacts that are part of the same Work
  362. subscription with the associated additional Work properties.
  363. type: array
  364. items:
  365. <<: *work-contact
  366. description: A Work contact.
  367. work-directory-request-wildcard: &work-directory-request-wildcard
  368. type: object
  369. required:
  370. - query
  371. - page
  372. - cateogries
  373. properties:
  374. identity:
  375. <<: *identity
  376. description: The user's Threema ID.
  377. page: *work-directory-page-index
  378. query:
  379. description: Wildcard search query.
  380. type: string
  381. const: '*'
  382. categories:
  383. <<: *work-user-category-ids
  384. description: At least one category ID to narrow down the search with.
  385. minLength: 1
  386. sort: *work-directory-sort
  387. work-directory-request-specific: &work-directory-request-specific
  388. type: object
  389. required:
  390. - query
  391. - page
  392. properties:
  393. identity:
  394. <<: *identity
  395. description: The user's Threema ID.
  396. page: *work-directory-page-index
  397. query:
  398. description: |-
  399. Search query. Matches any of Threema ID, first name, or last name.
  400. type: string
  401. minLength: 3
  402. example: Bob
  403. categories:
  404. <<: *work-user-category-ids
  405. description: Optional category IDs to narrow down the search with.
  406. sort: *work-directory-sort
  407. work-directory-response: &work-directory-response
  408. type: object
  409. required:
  410. - contacts
  411. - paging
  412. properties:
  413. paging:
  414. description: Page information.
  415. type: object
  416. required:
  417. - size
  418. - total
  419. properties:
  420. size:
  421. description: Maximum amount of results present in a single page.
  422. type: integer
  423. minimum: 0
  424. total:
  425. description: Total amount of results (spread across pages).
  426. type: integer
  427. minimum: 0
  428. prev:
  429. description: Previous page index, if any is available.
  430. type: integer
  431. minimum: 0
  432. next:
  433. description: Next page index, if any is available.
  434. type: integer
  435. minimum: 1
  436. contacts:
  437. description: |-
  438. A Work contact of the same subcription that matches the search query.
  439. type: array
  440. items: !merge-objects
  441. - *work-contact
  442. - type: object
  443. required:
  444. - org
  445. properties:
  446. csi: *work-user-identifier
  447. cat: *work-user-category-ids
  448. org: *work-organisation
  449. openapi: 3.1.0
  450. info:
  451. title: Directory and Work Sync Server API
  452. description: |-
  453. Maintains the directory of allocated Threema IDs and all associated
  454. properties.
  455. version: 1.0.0
  456. servers:
  457. - url: https://ds-apip.threema.ch
  458. description: Production server
  459. - url: https://ds-apip.test.threema.ch
  460. description: Sandbox server
  461. paths:
  462. /identity/update_work_info:
  463. post:
  464. summary: Work Properties
  465. description: |-
  466. Update Work properties associated to the currently used Threema ID. Only
  467. used by the _Work_ flavour of Threema.
  468. The first call without the challenge response properties initiates the
  469. challenge request. The second call must repeat the exact same properties
  470. and the challenge response.
  471. Note that all data of the request must be sourced **exclusively** from
  472. MDM parameters. For example, the data source for `nickname` must be
  473. `th_nickname` and not the custom nickname chosen by the user.
  474. TODO(SE-368): When sending/receiving steps.
  475. requestBody:
  476. required: true
  477. content:
  478. application/json:
  479. schema:
  480. oneOf:
  481. - *update-work-data-request
  482. - !merge-objects
  483. - *auth-challenge-response
  484. - *update-work-data-request
  485. responses:
  486. '200':
  487. description: Success... or not.
  488. content:
  489. application/json:
  490. schema:
  491. oneOf:
  492. - *auth-challenge-request
  493. - *update-work-data-response-ok
  494. - *update-work-data-response-error
  495. '429':
  496. description: Rate limit exceeded.
  497. /fetch2:
  498. post:
  499. summary: Work Sync
  500. description: |-
  501. Full sync of all data associated to the Work subscription. Only used by
  502. the _Work_ flavour of Threema.
  503. TODO(SE-368): When sending/receiving steps.
  504. servers: *work-servers
  505. requestBody:
  506. required: true
  507. content:
  508. application/json:
  509. schema: !merge-objects
  510. - *work-auth
  511. - *sync-work-data-request
  512. responses:
  513. '200':
  514. description: Work subscription data.
  515. content:
  516. application/json:
  517. schema: *sync-work-data-response
  518. '400':
  519. description: Invalid request.
  520. '401':
  521. description: Invalid username or password.
  522. '429':
  523. description: Rate limit exceeded.
  524. /identities:
  525. post:
  526. summary: Work Contacts
  527. description: |-
  528. Request properties associated to a contact of the same Work subscription.
  529. TODO(SE-368): When sending/receiving steps. Send before adding a new
  530. contact.
  531. servers: *work-servers
  532. requestBody:
  533. required: true
  534. content:
  535. application/json:
  536. schema: !merge-objects
  537. - *work-auth
  538. - *work-contacts-request
  539. responses:
  540. '200':
  541. description: Matching Work contacts in the same Work subscription.
  542. content:
  543. application/json:
  544. schema: *work-contacts-response
  545. '400':
  546. description: Invalid request.
  547. '401':
  548. description: Invalid username or password.
  549. '429':
  550. description: Rate limit exceeded.
  551. /directory:
  552. post:
  553. summary: Work Directory
  554. description: |-
  555. Search for contacts in the same Work subscription as the user.
  556. TODO(SE-368): When sending/receiving steps.
  557. servers: *work-servers
  558. requestBody:
  559. required: true
  560. content:
  561. application/json:
  562. schema:
  563. oneOf:
  564. - !merge-objects
  565. - *work-auth
  566. - *work-directory-request-wildcard
  567. - !merge-objects
  568. - *work-auth
  569. - *work-directory-request-specific
  570. responses:
  571. '200':
  572. description: Queried Work contacts of the same Work subscription.
  573. content:
  574. application/json:
  575. schema: *work-directory-response
  576. '400':
  577. description: Invalid request.
  578. '401':
  579. description: Invalid username or password.
  580. '429':
  581. description: Rate limit exceeded.