blahrs/docs/webapi.yaml
2024-10-16 07:26:00 -04:00

676 lines
20 KiB
YAML

openapi: 3.1.0
info:
title: Blah Chatserver Proto
version: 0.0.1
paths:
/_blah/server:
get:
summary: Get Server metadata
responses:
200:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ServerMetadata'
# OAPI does not support WebSocket interface definitions.
# See: https://github.com/OAI/OpenAPI-Specification/issues/55#issuecomment-929382279
/_blah/ws:
get:
summary: WebSocket endpoint
description: |
This endpoint is for server-side-event dispatching.
Once connected, client must send a JSON text message of type
`Signed_Auth` for authentication.
If server does not close it immediately, it means success.
Since OAPI does not support WebSocket interface, we use request and
response types documented here mean outgoing and incoming JSON text
messages.
parameters:
- name: Connection
in: header
required: true
- name: Upgrade
in: header
required: true
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ClientEvent'
responses:
101:
headers:
Connection:
required: true
Upgrade:
required: true
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ServerEvent'
/_blah/user/me:
get:
summary: Check registration status of the current user
parameters:
- name: Authorization
in: header
description: Optional user authentication token.
schema:
$ref: 'types.json#/components/schemas/Signed_AuthPayload'
responses:
204:
description: The user is already registered on the server.
404:
description: |
The user is not registered, or no token is not provided.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponseWithChallenge'
post:
summary: Register or update user identity
description: |
Register or update a user identity description.
To prevent misuse and DOS of this endpoint, the request must pass the
server-specific Proof of Work (PoW) challenge as below:
1. The request payload must include `challenge_nonce` with the value
of `x-blah-nonce` header from a recent enough GET response of
`/user/me`. Server will rotate it and a nonce will expire after a
server-specific time period.
2. The SHA256 of the canonical serialization (JCS) of `signee` must
have at least `x-blah-difficulty` (from a recent response) number
of leading zero bits.
The `id_url` should be a HTTPS domain name without path. A fixed
well-known path `/.well-known/blah.identity.json` will be fetched.
It should return status 200, with a JSON response of type
`UserIdentityDescription`.
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_UserRegisterPayload'
responses:
204:
description: User successfully registered.
400:
description: Invalid request format or any invalid fields in the request.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
401:
description: |
Unable to verify user identity. May caused by connection failure
when fetching id_url, malformed identity description, and etc.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
403:
description: |
Server disallows registration, either due to server restriction or
unacceptable id_url.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
409:
description: |
User state changed during the operation. Could retry later.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
422:
description: |
Fail to process identity description. Could be failure to fetch
remote description, unacceptable result from id_url, or any fields
(eg. signatures) in the returned description being invalid.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/room:
get:
summary: List rooms
parameters:
- name: filter
in: query
required: true
schema:
enum:
- public
- joined
- unseen
description: |
Must be one of following values:
- "public": list all public rooms on the server.
- "joined": list rooms the user have joined.
Requires `Authorization`.
- "unseen": list rooms the user have joined and have unseen
messages.
Requires `Authorization`.
- name: top
in: query
schema:
type: string
description:
The maximum count of rooms returned in a single response. This is
only an advice and server can clamp it to a smaller value.
- name: skipToken
in: query
schema:
type: string
description:
The page token returned from a previous list response to fetch the
next page. NB. Other parameters (eg. `joined` and `page_len`)
should be included (as the same value) for each page fetch.
- name: Authorization
in: header
description: Optional proof of membership for private rooms.
schema:
$ref: 'types.json#/components/schemas/Signed_AuthPayload'
responses:
200:
description: Filtered and paged rooms.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/RoomList'
401:
description: Missing or invalid Authorization header.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
post:
summary: Create a room
description:
When `typ="create_room"`, create a multi-user room.
When `typ="create_peer_chat"`, create a peer-to-peer room between two
users. There can be at most one peer room for each given user pair.
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_CreateRoomPayload'
responses:
200:
description: Room created.
content:
application/json:
schema:
type: string
description: Newly created room `rid`.
403:
description: The user does not have permission to create room.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
404:
description: |
The current user does not exists, the peer user does not exist or
they disallows peer chat.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
409:
description: There is already a peer chat room between the user pair.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/room/create:
post:
summary: Create a room (legacy)
deprecated: true
description: |
Alias of POST `/_blah/room`.
/_blah/room/{rid}:
get:
summary: Get room metadata
parameters:
- name: Authorization
in: header
description: Optional proof of membership for private rooms.
schema:
$ref: 'types.json#/components/schemas/Signed_AuthPayload'
responses:
200:
description: The metadata of the specified room.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/RoomMetadata'
404:
description: |
Room does not exist or the user does not have permission to get metadata of it.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
delete:
summary: Delete a room
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_DeleteRoomPayload'
responses:
204:
description: Operation completed.
401:
description: Missing or invalid Authorization header.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
404:
description: |
Room does not exist or the user does not have permission to access it.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/room/{rid}/admin:
post:
summary: Room management (legacy)
deprecated: true
description: |
Use POST `/_blah/room/{rid}/member` or
DELETE `/_blah/room/{rid}/member/{member_id_key}` instead.
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_RoomAdminPayload'
responses:
204:
description: Operation completed.
404:
description: |
Room does not exist or the user does not have permission for the
operation.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
409:
description:
Operation is already done, eg. joining an already joined room.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/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: 'types.json#/components/schemas/ErrorResponse'
/_blah/room/{rid}/feed.atom:
get:
summary: Get Atom feed of room
description: |
Get room {rid}'s content in The Atom Syndication Format format. The
room must be public. For human and feed reader consumption only.
More details: <https://validator.w3.org/feed/docs/atom.html>
responses:
200:
description: The Atom feed.
content:
application/atom+xml:
description: Feed XML.
404:
description: Room does not exist or is private.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/room/{rid}/msg:
get:
summary: List messages in a room
description: |
Return a list of messages in reversed server time order, up to length `top`
in a single response, from room {rid}.
The last (oldest) message's `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: 'types.json#/components/schemas/Signed_AuthPayload'
- name: top
in: query
schema:
type: integer
description: |
The number of items returned in a single response. 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: 'types.json#/components/schemas/RoomMsgs'
404:
description: |
Room does not exist or the user does not have permission to read it.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
post:
summary: Post a `Msg` into a room
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_ChatPayload'
responses:
200:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Id'
description: Newly created message id `cid`.
403:
description: The user does not have permission to post in this room.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
404:
description: The room does not exist or the user is not a room member.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/room/{rid}/msg/{cid}/seen:
post:
summary: Mark a message seen
description: |
Mark message {cid} and everything before it in room {rid} seen by the
current user.
Server may enforce that last seen message does not go backward. Marking
an older message 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: 'types.json#/components/schemas/Signed_AuthPayload'
responses:
204:
description: Operation completed.
404:
description: |
Room does not exist or the user is not in the room.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/room/{rid}/member:
get:
summary: List room members
parameters:
- name: Authorization
in: header
required: true
description: Proof of membership.
schema:
$ref: 'types.json#/components/schemas/Signed_AuthPayload'
- name: top
in: query
schema:
type: string
description:
The maximum count of rooms returned in a single response. This is
only an advice and server can clamp it to a smaller value.
- name: skipToken
in: query
schema:
type: string
description:
The page token returned from a previous list response to fetch the
next page.
responses:
200:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/RoomMemberList'
403:
description: |
The user does not have permission to get room members
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
404:
description: |
Room does not exist or the user is not in the room.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
post:
summary: Join a room
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_AddMemberPayload'
responses:
204:
description: Operation completed.
404:
description: |
Room does not exist or the user does not have permission for the
operation.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
409:
description:
The user is already a room member.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
/_blah/room/{rid}/member/{member_id_key}:
get:
summary: Get information of a room member
parameters:
- name: Authorization
in: header
description: User authentication token.
schema:
$ref: '#/components/schemas/Signed-Auth'
responses:
200:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
404:
description: |
Room does not exist, the user does not have permission for the
operation, or the operand user is not a room member.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ErrorResponse'
patch:
summary: Update permission of a room member
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_UpdateMember'
responses:
204:
description: Operation completed.
403:
description: |
The user does not have permission to update permission of the
given user.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ServerMetadata'
404:
description: |
Room does not exist, the user does not have permission for the
operation, or the operand user is not a room member.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ServerMetadata'
delete:
summary: Remove a room member.
requestBody:
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/Signed_RemoveMember'
responses:
204:
description: Operation completed.
403:
description: |
The user does not have permission to remove the operand member.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ServerMetadata'
404:
description: |
Room does not exist, the user does not have permission for the
operation, or the operand user is not a room member.
content:
application/json:
schema:
$ref: 'types.json#/components/schemas/ServerMetadata'