mirror of
https://github.com/Blah-IM/blahrs.git
synced 2025-05-01 00:31:09 +00:00
676 lines
20 KiB
YAML
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'
|