doc: update and fix errors

This commit is contained in:
oxalica 2024-09-10 03:02:10 -04:00
parent 3bb6d1456d
commit 8bca2ebddc

View file

@ -6,7 +6,7 @@ info:
paths: paths:
/ws: /ws:
get: get:
summary: WebSocket endpoint. summary: WebSocket endpoint
description: | description: |
Once connection, client must send a JSON text message of type Once connection, client must send a JSON text message of type
`WithSig<AuthPayload>` for authentication. `WithSig<AuthPayload>` for authentication.
@ -18,89 +18,106 @@ paths:
/room: /room:
get: get:
summary: List rooms on the server summary: List rooms
parameters: parameters:
filter: - name: filter
in: query in: query
required: true required: true
schema:
enum:
- public
- joined
- unseen
description: | description: |
Must be one of following values: Must be one of following values:
- "public": list all public rooms on the server. - "public": list all public rooms on the server.
- "joined": list rooms the user have joined. - "joined": list rooms the user have joined.
Requires `Authorization`.
- "unseen": list rooms the user have joined and have unseen - "unseen": list rooms the user have joined and have unseen
messages. messages.
top: Requires `Authorization`.
- name: top
in: query in: query
schema:
type: string
description: description:
The maximum number of items returned in each page. This is only an The maximum number of items returned in each page. This is only an
advice and server can clamp it to a smaller value. advice and server can clamp it to a smaller value.
skipToken:
- name: skipToken
in: query in: query
schema:
type: string
description: description:
The page token returned from a previous list response to fetch the The page token returned from a previous list response to fetch the
next page. NB. Other parameters (eg. `joined` and `page_len`) next page. NB. Other parameters (eg. `joined` and `page_len`)
should be included (as the same value) for each page fetch. should be included (as the same value) for each page fetch.
headers:
Authorization: - name: Authorization
description: | in: header
Proof of membership for private rooms. description: Optional proof of membership for private rooms.
Required if `filter` is other than "public".
required: false
schema: schema:
$ret: WithSig<AuthPayload> $ref: '#/components/schemas/WithSig-Auth'
responses: responses:
200: 200:
description: Filtered and paged rooms.
content: content:
application/json: application/json:
$ref: '#/components/schema/RoomList' schema:
$ref: '#/components/schemas/RoomList'
401: 401:
description: Missing or invalid Authorization header. description: Missing or invalid Authorization header.
content: content:
application/json: application/json:
$ref: '#/components/schemas/ApiError' schema:
$ref: '#/components/schemas/ApiError'
/room/create: /room/create:
post: post:
summary: Create a new room summary: Create room
requestBody: requestBody:
content: content:
application/json: application/json:
schema: schema:
$ref: WithSig<CreateRoomPayload> $ref: '#/components/schemas/WithSig-CreateRoom'
example:
sig: 99a77e836538268839ed3419c649eefb043cb51d448f641cc2a1c523811aab4aacd09f92e7c0688ffd659bfc6acb764fea79979a491e132bf6a56dd23adc1d09
signee:
nonce: 670593955
payload:
typ: create_room
attrs: 1 # PUBLIC_READABLE
title: 'hello room'
members:
- user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
permission: -1
timestamp: 1724966284
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
responses: responses:
200: 200:
description: Room created.
content: content:
application/json: application/json:
type: string schema:
description: Id of the newly created room (rid). type: string
description: Newly created room `rid`.
403: 403:
description: The user does not have permission to create room. description: The user does not have permission to create room.
content: content:
application/json: application/json:
$ref: '#/components/schemas/ApiError' schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}: /room/{rid}:
get: get:
summary: Get room metadata summary: Get room metadata
parameters:
- name: Authorization
in: header
description: Optional proof of membership for private rooms.
schema:
$ref: '#/components/schemas/WithSig-Auth'
responses: responses:
200: 200:
description: The metadata of the specified room.
content: content:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/RoomMetadata' $ref: '#/components/schemas/RoomMetadata'
404: 404:
description: | description: |
Room does not exist or the user does not have permission to get metadata of it. Room does not exist or the user does not have permission to get metadata of it.
@ -109,138 +126,28 @@ paths:
schema: schema:
$ref: '#/components/schemas/ApiError' $ref: '#/components/schemas/ApiError'
/room/{rid}/admin:
/room/{rid}/feed.json:
get:
summary: JSON feed of room {rid}, which must be public readable
description: For human and feed reader consumption only.
responses:
200:
text/feed+json:
scheme:
$ref: 'https://www.jsonfeed.org/version/1.1/'
404:
description: Room does not exist or is private.
content:
application/json:
$ref: '#/components/schemas/ApiError'
/room/{rid}/item:
get:
summary: Get chat history for room {rid}
description: |
Return chat items in reversed time order, up to PAGE_LEN items.
The last (oldest) chat id can be used as query parameter for the next
GET, to repeatedly fetch full history.
headers:
Authorization:
description: Proof of membership for private rooms.
required: false
schema:
$ret: WithSig<AuthPayload>
parameters:
top:
in: query
description: |
The maximum number of items to return. This is an advice and may be
ignored by server.
skipToken:
in: query
description: |
Retrieve the next page of items, by providing the last item's `cid`
from the previous response.
responses:
200:
content:
application/json:
x-description: TODO
404:
description: |
Room does not exist or the user does not have permission to read it.
content:
application/json:
$ref: '#/components/schemas/ApiError'
post: post:
summary: Post a chat in room {rid} summary: Room management
requestBody: requestBody:
content: content:
application/json: application/json:
schema: schema:
$ref: WithItemId<WithSig<ChatPayload>> $ref: '#/components/schemas/WithSig-RoomAdmin'
example:
sig: 99a77e836538268839ed3419c649eefb043cb51d448f641cc2a1c523811aab4aacd09f92e7c0688ffd659bfc6acb764fea79979a491e132bf6a56dd23adc1d09
signee:
nonce: 670593955
payload:
typ: chat
room: 7ed9e067-ec37-4054-9fc2-b1bd890929bd
rich_text: ["before ",["bold ",{"b":true}],["italic bold ",{"b":true,"i":true}],"end"]
timestamp: 1724966284
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
responses:
200:
content:
application/json:
type: string
description: Created chat id (cid).
400:
description: Body is invalid or fails the verification.
content:
application/json:
$ref: '#/components/schemas/ApiError'
403:
description: |
The user does not have permission to post in this room, or the room does not exist.
content:
application/json:
$ref: '#/components/schemas/ApiError'
/room/{rid}/item/{cid}/seen:
post:
summary: Mark item {cid} in room {rid} seen by the current user.
description:
Server will enforce that last seen item does not go backward. Marking
an older item seen or sending the same request multiple times will be a
no-op.
headers:
Authorization:
description: Proof of membership for private rooms.
schema:
$ret: WithSig<AuthPayload>
responses: responses:
204: 204:
description: Operation completed. description: Operation completed.
404:
description: | 409:
Room does not exist or the user is not in the room. description:
Operation is already done, eg. joining an already joined room.
content: content:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/ApiError' $ref: '#/components/schemas/ApiError'
/room/{rid}/admin:
post:
summary: Room management
requestBody:
content:
application/json:
schema:
$ref: WithSig<AdminPayload>
example:
sig: 99a77e836538268839ed3419c649eefb043cb51d448f641cc2a1c523811aab4aacd09f92e7c0688ffd659bfc6acb764fea79979a491e132bf6a56dd23adc1d09
signee:
nonce: 670593955
payload:
permission: 1
room: 7ed9e067-ec37-4054-9fc2-b1bd890929bd
typ: add_member
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
timestamp: 1724966284
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
responses:
204:
description: Operation completed.
404: 404:
description: | description: |
Room does not exist or the user does not have permission for management. Room does not exist or the user does not have permission for management.
@ -249,6 +156,132 @@ paths:
schema: schema:
$ref: '#/components/schemas/ApiError' $ref: '#/components/schemas/ApiError'
/room/{rid}/feed.json:
get:
summary: Get JSON feed of room
description: |
Get room {rid}'s content in JSON feed v1.1 format. The room must be
public. For human and feed reader consumption only.
responses:
200:
description: The JSON feed.
content:
text/feed+json:
schema:
$ref: 'https://www.jsonfeed.org/version/1.1/'
404:
description: Room does not exist or is private.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}/item:
get:
summary: List items in room
description: |
Return items in reversed time order, up to `skipToken` items in a
single response, from room {rid}.
The last (oldest) chat `cid` will be returned as `skipToken` in
response, which can be used as query parameter for the next GET, to
repeatedly fetch more history.
parameters:
- name: Authorization
in: header
description: Optional proof of membership for private rooms.
schema:
$ref: '#/components/schemas/WithSig-Auth'
- name: top
in: query
schema:
type: integer
description: |
The maximum number of items to return. This is an advice and may be
further clamped by the server. It must not be zero.
- name: skipToken
in: query
schema:
type: string
description: |
Return items after (older than) an existing `cid`. Useful for
pagination.
responses:
200:
content:
application/json:
schema:
$ref: '#/components/schemas/RoomItems'
404:
description: |
Room does not exist or the user does not have permission to read it.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
post:
summary: Post item in room
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WithSig-Chat'
responses:
200:
content:
application/json:
schema:
type: string
description: Newly created item `cid`.
# FIXME: Distinguish this from 404?
403:
description: |
The user does not have permission to post in this room, or the room does not exist.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
/room/{rid}/item/{cid}/seen:
post:
summary: Mark item seen
description: |
Mark item {cid} in room {rid} seen by the current user.
Server may enforce that last seen item does not go backward. Marking
an older item seen or sending the same request multiple times can be a
no-op.
parameters:
- name: Authorization
in: header
required: true
description: Proof of membership for private rooms.
schema:
$ref: '#/components/schemas/WithSig-Auth'
responses:
204:
description: Operation completed.
404:
description: |
Room does not exist or the user is not in the room.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
# Ideally we should generate these from src, but we need to
# WAIT: https://github.com/juhaku/utoipa/pull/1034
components: components:
schemas: schemas:
ApiError: ApiError:
@ -259,8 +292,12 @@ components:
properties: properties:
code: code:
type: string type: string
description: A machine-readable error code string.
example: invalid_signature
message: message:
type: string type: string
description: A human-readable error message.
example: signature verification failed
RoomList: RoomList:
type: object type: object
@ -284,21 +321,32 @@ components:
title: title:
type: string type: string
attrs: attrs:
type: int64 description: Room attributes bitset, see `RoomAttrs`.
type: integer
format: int64
last_chat: last_chat:
$ref: 'WithItemId<WithSig<ChatPayload>>' $ref: '#/components/schemas/WithItemId-WithSig-Chat'
last_seen_cid: last_seen_cid:
description: The `cid` of the last chat being marked as seen.
type: string type: string
unseen_cnt:
description: |
The number of unseen messages. Only available for
GET `/room?filter=unseen`.
type: integer
format: uint64
RoomMetadata: RoomMetadata:
type: object type: object
required: ['rid', 'title', 'attrs']
properties: properties:
rid: rid:
type: string type: string
title: title:
type: string type: string
attrs: attrs:
type: int64 type: integer
format: int64
RoomItems: RoomItems:
type: object type: object
@ -306,8 +354,200 @@ components:
- items - items
properties: properties:
items: items:
description: Room items in reversed server-received time order.
type: array type: array
items: items:
$ref: 'WithItemId<WithSig<ChatPayload>>' $ref: '#/components/schemas/WithItemId-WithSig-Chat'
skip_token: skip_token:
description: The token for fetching the next page.
type: string type: string
RichText:
type: array
items:
anyOf:
- type: string
description: Unstyled text piece.
- type: array
items: false
prefixItems:
- type: string
description: The text piece to apply styles on.
- type: object
properties:
b:
type: boolean
description: Bold.
m:
type: boolean
description: Monospace.
i:
type: boolean
description: Italic.
s:
type: boolean
description: Strikethrough.
u:
type: boolean
description: Underline.
hashtag:
type: boolean
description: Hashtag.
link:
type: string
description: Link target.
WithSig-Auth:
type: object
properties:
sig:
type: string
signee:
type: object
properties:
nonce:
type: integer
format: uint32
payload:
type: object
properties:
typ:
type: string
const: 'auth'
WithSig-RoomAdmin:
type: object
properties:
sig:
type: string
signee:
type: object
properties:
nonce:
type: integer
format: uint32
payload:
oneOf:
- description: Add member to the room.
type: object
properties:
typ:
type: string
const: 'add_member'
room:
type: string
permission:
type: integer
format: uint64
user:
type: string
- description: Remove member from the room.
type: object
properties:
typ:
type: string
const: 'remove_member'
room:
type: string
user:
type: string
example:
sig: 99a77e836538268839ed3419c649eefb043cb51d448f641cc2a1c523811aab4aacd09f92e7c0688ffd659bfc6acb764fea79979a491e132bf6a56dd23adc1d09
signee:
nonce: 670593955
payload:
permission: 1
room: 7ed9e067-ec37-4054-9fc2-b1bd890929bd
typ: add_member
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
timestamp: 1724966284
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
WithSig-Chat:
type: object
properties:
sig:
type: string
signee:
type: object
properties:
nonce:
type: integer
format: uint32
payload:
type: object
properties:
typ:
type: string
const: 'chat'
room:
type: string
rich_text:
$ref: '$/components/schemas/RichText'
example:
sig: 99a77e836538268839ed3419c649eefb043cb51d448f641cc2a1c523811aab4aacd09f92e7c0688ffd659bfc6acb764fea79979a491e132bf6a56dd23adc1d09
signee:
nonce: 670593955
payload:
typ: chat
room: 7ed9e067-ec37-4054-9fc2-b1bd890929bd
rich_text: ["before ",["bold ",{"b":true}],["italic bold ",{"b":true,"i":true}],"end"]
timestamp: 1724966284
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
WithItemId-WithSig-Chat:
allOf:
- $ref: '#/components/schemas/WithSig-Chat'
- type: object
properties:
cid:
type: string
description: An opaque server-specific item identifier.
WithSig-CreateRoom:
type: object
properties:
sig:
type: string
signee:
type: object
properties:
nonce:
type: integer
format: uint32
payload:
type: object
properties:
typ:
type: string
const: 'create_room'
title:
type: string
members:
type: array
items:
type: object
properties:
user:
type: string
permission:
type: integer
format: int64
example:
sig: 99a77e836538268839ed3419c649eefb043cb51d448f641cc2a1c523811aab4aacd09f92e7c0688ffd659bfc6acb764fea79979a491e132bf6a56dd23adc1d09
signee:
nonce: 670593955
payload:
typ: create_room
attrs: 1 # PUBLIC_READABLE
title: 'hello room'
members:
- user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7
permission: -1
timestamp: 1724966284
user: 83ce46ced47ec0391c64846cbb6c507250ead4985b6a044d68751edc46015dd7