1381 lines
47 KiB
YAML
1381 lines
47 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: WebDrop API
|
|
version: 8.0.0
|
|
servers:
|
|
- url: /api/v1
|
|
|
|
tags:
|
|
- name: server
|
|
- name: channel
|
|
- name: join
|
|
- name: frame
|
|
- name: item
|
|
- name: share
|
|
- name: account
|
|
|
|
paths:
|
|
/accounts/profile:
|
|
get:
|
|
tags: [account]
|
|
parameters:
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountProfile'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
patch:
|
|
tags: [account]
|
|
parameters:
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/AccountProfileRequest' }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountProfile'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/accounts/spaces:
|
|
get:
|
|
tags: [account]
|
|
parameters:
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items: { $ref: '../contracts/api.schemas.json#/$defs/ChannelInfo' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/structure:
|
|
get:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: false
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/Role'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/channels:
|
|
post:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceChannelRequest' }
|
|
responses:
|
|
'201':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceChannelCreatedBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/channels/{channelId}:
|
|
patch:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: channelId
|
|
in: path
|
|
required: true
|
|
schema: { type: string, format: uuid }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceNameRequest' }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/channels/{channelId}/group:
|
|
put:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: channelId
|
|
in: path
|
|
required: true
|
|
schema: { type: string, format: uuid }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceGroupRequest' }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/groups:
|
|
post:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceNameRequest' }
|
|
responses:
|
|
'201':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceGroupCreatedBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/groups/{groupId}:
|
|
patch:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: groupId
|
|
in: path
|
|
required: true
|
|
schema: { type: string, format: uuid }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceNameRequest' }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/folders:
|
|
post:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceFolderRequest' }
|
|
responses:
|
|
'201':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/folders/{folderId}:
|
|
patch:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: folderId
|
|
in: path
|
|
required: true
|
|
schema: { type: string, format: uuid }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceNameRequest' }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/spaces/{id}/locations:
|
|
put:
|
|
tags: [channel]
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema: { type: string }
|
|
- name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
schema: { type: string }
|
|
- $ref: '#/components/parameters/RoleWriter'
|
|
- $ref: '#/components/parameters/Account'
|
|
- name: Authorization
|
|
in: header
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '../contracts/api.schemas.json#/$defs/WorkspaceMoveRequest' }
|
|
responses:
|
|
'200':
|
|
description: 服务端权威数据
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '../contracts/api.schemas.json#/$defs/WorkspaceBody'
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/accounts/channels:
|
|
get:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 领取当前账号已加入频道的加密密钥包
|
|
responses:
|
|
'200':
|
|
description: 仅返回已加入频道
|
|
content:
|
|
application/json:
|
|
schema: { type: array, items: { $ref: '#/components/schemas/AccountChannel' } }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
/accounts/devices:
|
|
get:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 读取当前账号的设备会话
|
|
responses:
|
|
'200':
|
|
description: 设备列表
|
|
content:
|
|
application/json:
|
|
schema: { type: array, items: { $ref: '#/components/schemas/AccountDevice' } }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
/accounts/devices/{id}:
|
|
parameters:
|
|
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
|
|
patch:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 重命名本账号设备
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [name]
|
|
properties: { name: { type: string, minLength: 1, maxLength: 80 } }
|
|
responses:
|
|
'204': { description: 已更新 }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
delete:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 撤销该设备的全部 sessions,保留账号成员资格
|
|
responses:
|
|
'204': { description: 已撤销 }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
/channels/{id}/key-package:
|
|
put:
|
|
tags: [channel]
|
|
security: [{ bearer: [] }]
|
|
summary: 频道主补齐给自己账号的加密密钥包
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [payload]
|
|
properties: { payload: { type: string, minLength: 1, maxLength: 16384 } }
|
|
responses:
|
|
'204': { description: 已保存 }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
/info:
|
|
get:
|
|
tags: [server]
|
|
security: []
|
|
summary: 服务端能力与限制
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ServerInfo' }
|
|
|
|
/accounts:
|
|
post:
|
|
tags: [account]
|
|
security: []
|
|
summary: 创建账号
|
|
description: 仅接收口令 verifier 和客户端加密保险库,不接收密码。
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountRegister' }
|
|
responses:
|
|
'204': { description: 已创建 }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
'429': { $ref: '#/components/responses/Error' }
|
|
|
|
/accounts/salt:
|
|
post:
|
|
tags: [account]
|
|
security: []
|
|
summary: 查询账号口令派生 salt
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountSaltRequest' }
|
|
responses:
|
|
'200':
|
|
description: 客户端 PBKDF2 salt
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountSalt' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
|
|
/accounts/session:
|
|
post:
|
|
tags: [account]
|
|
security: []
|
|
summary: 验证客户端派生凭据并创建 session
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountSessionRequest' }
|
|
responses:
|
|
'200':
|
|
description: 已登录
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountSession' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
delete:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 撤销当前账号 session
|
|
responses:
|
|
'204': { description: 已撤销 }
|
|
|
|
/accounts/vault:
|
|
get:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 读取客户端加密保险库
|
|
responses:
|
|
'200':
|
|
description: 当前保险库和 revision
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountVault' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
put:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 以 revision 乐观并发更新保险库
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountVault' }
|
|
responses:
|
|
'200':
|
|
description: 已更新
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AccountVault' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
|
|
/accounts/users/{username}/key:
|
|
get:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 查询被邀请用户公钥
|
|
parameters:
|
|
- { name: username, in: path, required: true, schema: { type: string } }
|
|
responses:
|
|
'200':
|
|
description: 公钥
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/PublicKey' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
/accounts/invitations:
|
|
get:
|
|
tags: [account]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 当前账号收到的邀请
|
|
responses:
|
|
'200':
|
|
description: 邀请列表
|
|
content:
|
|
application/json:
|
|
schema: { type: array, items: { $ref: '#/components/schemas/ChannelInvitation' } }
|
|
/channels/{id}/members:
|
|
get:
|
|
tags: [channel]
|
|
security: [{ bearer: [] }]
|
|
summary: 读取频道内账号成员及角色
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
responses:
|
|
'200':
|
|
description: 成员列表
|
|
content:
|
|
application/json:
|
|
schema: { type: array, items: { $ref: '#/components/schemas/ChannelMember' } }
|
|
/channels/{id}/invitations:
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
get:
|
|
tags: [channel]
|
|
security: [{ bearer: [], accountBearer: [] }]
|
|
summary: 频道主查询邀请
|
|
responses:
|
|
'200':
|
|
description: 邀请列表
|
|
content:
|
|
application/json:
|
|
schema: { type: array, items: { $ref: '#/components/schemas/ChannelInvitation' } }
|
|
post:
|
|
tags: [channel]
|
|
security: [{ bearer: [], accountBearer: [] }]
|
|
summary: 原子提交账号邀请及服务端授权计划要求的域密钥包
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/InvitationRequest' }
|
|
responses:
|
|
'204': { description: 已邀请 }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/channels/{id}/invitations/{username}/crypto-plan:
|
|
get:
|
|
tags: [channel]
|
|
security: [{ bearer: [], accountBearer: [] }]
|
|
summary: 获取新成员域密钥封装计划
|
|
description: 返回由服务端历史策略和当前成员权限计算的 epoch 与收件人集合;提交时服务端会重新计算并校验。
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
- { name: username, in: path, required: true, schema: { type: string } }
|
|
responses:
|
|
'200':
|
|
description: 服务端计算的加密授权计划
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/InvitationCryptoPlan' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
/channels/{id}/invitations/{username}:
|
|
delete:
|
|
tags: [channel]
|
|
security: [{ bearer: [], accountBearer: [] }]
|
|
summary: 撤销邀请和成员授权并移除其设备
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
- { name: username, in: path, required: true, schema: { type: string } }
|
|
responses:
|
|
'204': { description: 已移除 }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
|
|
/channels:
|
|
post:
|
|
tags: [channel]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 创建频道
|
|
description: |
|
|
服务端启用验证码时需要 `X-WD-Cap`(Cap 的 token,见 protocol §11),并需要终端头 `X-WD-Endpoint`。
|
|
创建者的账号自动成为该频道 owner,其终端自动入席。
|
|
parameters:
|
|
- { $ref: '#/components/parameters/Captcha' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/CreateChannelRequest' }
|
|
responses:
|
|
'201':
|
|
description: 已创建
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ChannelInfo' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
'428': { $ref: '#/components/responses/Error' }
|
|
'429': { $ref: '#/components/responses/Error' }
|
|
'503': { $ref: '#/components/responses/Error' }
|
|
|
|
/channels/{id}:
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
get:
|
|
tags: [channel]
|
|
summary: 读取频道信息(不占成员名额)
|
|
description: 需要账号会话。`members_used` 表示唯一账号成员数,不是设备数。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/Role' }
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ChannelInfo' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
delete:
|
|
tags: [channel]
|
|
summary: 删除整个频道及全部密文(所有者)
|
|
description: 有效的 owner 凭据即可调用,不要求 owner 终端登记。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
responses:
|
|
'204': { description: 已删除 }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
|
|
/channels/{id}/settings:
|
|
patch:
|
|
tags: [channel]
|
|
summary: 修改设置(所有者)
|
|
description: |
|
|
字段均可选,只修改提供的字段。`ttl_seconds` 的变更从现在起算。
|
|
成功后向订阅者推送 `{"t":"settings"}`。有效的 owner 凭据即可调用,不要求 owner 终端登记。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ChannelSettingsPatch' }
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ChannelInfo' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
|
|
/channels/{id}/join:
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
post:
|
|
tags: [join]
|
|
summary: 加入频道
|
|
description: |
|
|
幂等。必须带账号会话(没有则 401 `account_required`)。只登记成员关系:同一账号的多台设备不增加人数,此后仅凭账号会话鉴权。
|
|
成员名额已满返回 403 `members_full`。读取频道信息和 owner 管理接口不占名额;访问频道内容前必须已加入,否则 403 `not_joined`。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
requestBody:
|
|
required: false
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
password: { type: string, minLength: 8, maxLength: 256 }
|
|
responses:
|
|
'200':
|
|
description: 已加入
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/JoinResult' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
|
|
/channels/{id}/frames:
|
|
post:
|
|
tags: [frame]
|
|
summary: 追加一帧
|
|
description: |
|
|
请求体是完整的帧封装(26 字节头 + 负载),格式见 `protocol.md` §4。
|
|
幂等键为 `(channel_id, item_id, frame_index)`。内容相同则 200 返回原 seq,内容不同则 409。
|
|
第 0 帧可带 `X-WD-Max-Downloads`;名称与线程字段统一在条目元数据中。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/RoleWriter' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
- name: X-WD-Max-Downloads
|
|
in: header
|
|
required: false
|
|
schema: { type: integer, minimum: 0 }
|
|
description: 条目的下载上限,0 为不限。只对 GATED 条目生效。
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/octet-stream:
|
|
schema: { type: string, format: binary }
|
|
responses:
|
|
'201':
|
|
description: 新追加
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AppendResult' }
|
|
'200':
|
|
description: 幂等重发
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AppendResult' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
'413': { $ref: '#/components/responses/Error' }
|
|
'429': { $ref: '#/components/responses/Error' }
|
|
|
|
/channels/{id}/log:
|
|
get:
|
|
tags: [frame]
|
|
summary: 按 seq 拉取日志(长轮询、续传、全量同步)
|
|
description: |
|
|
返回日志记录的线格式拼接(`protocol.md` §8):每条 `seq(u64) ‖ kind(u8) ‖ body`。
|
|
`wait>0` 时无新记录会挂起,最长 25 秒,超时返回空体。
|
|
满足 `0 < from < oldest_seq` 时返回 410 并带 `oldest_seq`,客户端必须从 `from=0` 全量同步并丢弃本地已不存在的条目(不要从 `oldest_seq` 读起)。`from=0` 永远允许。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
- name: from
|
|
in: query
|
|
required: false
|
|
schema: { type: integer, format: int64, minimum: 0, default: 0 }
|
|
- name: limit
|
|
in: query
|
|
required: false
|
|
schema: { type: integer, minimum: 1, maximum: 1000, default: 200 }
|
|
- name: wait
|
|
in: query
|
|
required: false
|
|
schema: { type: integer, minimum: 0, maximum: 25, default: 0 }
|
|
description: 长轮询等待秒数
|
|
responses:
|
|
'200':
|
|
description: 记录拼接,可为空
|
|
headers:
|
|
X-WD-Last-Seq:
|
|
description: 频道当前最新 seq
|
|
schema: { type: integer, format: int64 }
|
|
content:
|
|
application/octet-stream:
|
|
schema: { type: string, format: binary }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'410':
|
|
description: 0 < from < oldest_seq,需要从 0 全量同步
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/GoneLog' }
|
|
|
|
/channels/{id}/ws:
|
|
get:
|
|
tags: [frame]
|
|
security: []
|
|
summary: WebSocket 订阅(降级链第一级)
|
|
description: |
|
|
升级为 WebSocket。浏览器不能设置头,凭据通过子协议传递:
|
|
`Sec-WebSocket-Protocol: wd.v1, wd.role.<role>, wd.auth.<base64url(令牌)>, wd.ep.<base64url(S)>`,
|
|
服务端回选 `wd.v1`。不要把令牌放在 URL 里。
|
|
|
|
**服务端 → 客户端**
|
|
- 二进制消息:一条日志记录(`seq ‖ kind ‖ body`)。
|
|
- 文本消息(JSON):`{"t":"hb","seq":N}` 心跳(每 20 秒);`{"t":"settings"}` 设置变更;`{"t":"members"}` 成员变更。
|
|
|
|
客户端 45 秒收不到任何消息应判定死链,以指数退避(1~30 秒)加抖动重连,并带 `from=last_seq+1`。
|
|
上传不走 WebSocket,仍用 `POST /frames`。
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- name: from
|
|
in: query
|
|
required: false
|
|
schema: { type: integer, format: int64, minimum: 0, default: 0 }
|
|
responses:
|
|
'101': { description: 已升级 }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'410':
|
|
description: 0 < from < oldest_seq,需要从 0 全量同步
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/GoneLog' }
|
|
|
|
/channels/{id}/events:
|
|
get:
|
|
tags: [frame]
|
|
summary: SSE 订阅(降级链第二级)
|
|
description: |
|
|
`text/event-stream`。每个事件的 `id:` 是 seq,`data:` 是 base64url 的日志记录;
|
|
控制消息与 WebSocket 的文本消息相同,事件名为 `control`。
|
|
`EventSource` 不能设置头,前端应使用 `fetch` 流式读取并带头部鉴权。
|
|
续传用 `from` 或 `Last-Event-ID`。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
- name: from
|
|
in: query
|
|
required: false
|
|
schema: { type: integer, format: int64, minimum: 0, default: 0 }
|
|
responses:
|
|
'200':
|
|
description: 事件流
|
|
content:
|
|
text/event-stream:
|
|
schema: { type: string }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'410':
|
|
description: 0 < from < oldest_seq,需要从 0 全量同步
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/GoneLog' }
|
|
|
|
/channels/{id}/items/{itemId}/frames:
|
|
get:
|
|
tags: [item]
|
|
summary: 拉取条目的帧(GATED 条目的取数方式)
|
|
description: |
|
|
返回封装拼接,每帧自带 `payload_len`,可流式解析。条目尚未 FINAL 时响应持续输出直到 FINAL。
|
|
`from=0` 计一次下载;`from>0` 只有同一终端此前对同一条目成功启动过 `from=0` 才能续传,否则返回 410 `gone`。
|
|
达到下载上限后返回 410 `gone`,5 分钟宽限期后删除密文,宽限期内已开始的拉取可继续续传。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/ItemId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
- name: from
|
|
in: query
|
|
required: false
|
|
schema: { type: integer, format: int64, minimum: 0, default: 0 }
|
|
description: 起始 frame_index
|
|
responses:
|
|
'200':
|
|
description: 封装拼接
|
|
content:
|
|
application/octet-stream:
|
|
schema: { type: string, format: binary }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'410': { $ref: '#/components/responses/Error' }
|
|
|
|
/channels/{id}/items/{itemId}:
|
|
delete:
|
|
tags: [item]
|
|
summary: 删除条目
|
|
description: |
|
|
按频道的 `delete_policy` 授权:`owner_only` 仅所有者;`own` 时所有者或条目作者;`anyone` 时任意已入席终端。
|
|
成功后在日志追加 tombstone(`reason=0`)。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ChannelId' }
|
|
- { $ref: '#/components/parameters/ItemId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Account' }
|
|
responses:
|
|
'204': { description: 已删除 }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares:
|
|
post:
|
|
tags: [share]
|
|
security: [{ accountBearer: [] }]
|
|
summary: 创建便捷分享草稿
|
|
description: 启用验证码时需携带 Cap token。创建者 endpoint 可选,创建者不计入访客数。
|
|
parameters:
|
|
- { $ref: '#/components/parameters/Captcha' }
|
|
- { $ref: '#/components/parameters/ShareEndpoint' }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/CreateShareRequest' }
|
|
responses:
|
|
'201':
|
|
description: 已创建草稿
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ShareInfo' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
'428': { $ref: '#/components/responses/Error' }
|
|
'429': { $ref: '#/components/responses/Error' }
|
|
'503': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares/{id}:
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ShareId' }
|
|
get:
|
|
tags: [share]
|
|
summary: 读取分享信息
|
|
description: 已封存时使用 read;草稿仅 owner 可读,read 对草稿返回 not_found。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/Role' }
|
|
responses:
|
|
'200':
|
|
description: 分享与条目下载状态
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ShareInfo' }
|
|
'401': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
delete:
|
|
tags: [share]
|
|
summary: 删除草稿
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
responses:
|
|
'204': { description: 草稿已删除 }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares/{id}/settings:
|
|
patch:
|
|
tags: [share]
|
|
summary: 修改草稿设置
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ShareId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ShareSettingsPatch' }
|
|
responses:
|
|
'200':
|
|
description: 设置已更新
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ShareInfo' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares/{id}/frames:
|
|
post:
|
|
tags: [share]
|
|
summary: 向草稿追加加密帧
|
|
description: 不支持 SNAPSHOT。第 0 帧可用 X-WD-Max-Downloads 覆盖默认下载上限。响应的 seq 是 frame_index 确认值,不是日志游标。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ShareId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
- name: X-WD-Max-Downloads
|
|
in: header
|
|
required: false
|
|
schema: { type: integer, format: int64, minimum: 0 }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/octet-stream:
|
|
schema: { type: string, format: binary }
|
|
responses:
|
|
'201':
|
|
description: 新帧已追加
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AppendResult' }
|
|
'200':
|
|
description: 幂等重发
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/AppendResult' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
'413': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares/{id}/items/{itemId}:
|
|
delete:
|
|
tags: [share]
|
|
summary: 从草稿移除条目
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ShareId' }
|
|
- { $ref: '#/components/parameters/ItemId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
responses:
|
|
'204': { description: 条目已删除 }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares/{id}/finish:
|
|
post:
|
|
tags: [share]
|
|
summary: 封存分享
|
|
description: 验证 manifest 是单帧非 GATED 完整条目,且草稿内所有条目完整;成功后永久禁用写权限。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ShareId' }
|
|
- { $ref: '#/components/parameters/RoleOwner' }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/FinishShareRequest' }
|
|
responses:
|
|
'200':
|
|
description: 分享已封存
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/ShareInfo' }
|
|
'400': { $ref: '#/components/responses/Error' }
|
|
'409': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares/{id}/manifest:
|
|
get:
|
|
tags: [share]
|
|
summary: 获取加密清单帧
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ShareId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Endpoint' }
|
|
responses:
|
|
'200':
|
|
description: 完整封装的二进制清单
|
|
content:
|
|
application/octet-stream:
|
|
schema: { type: string, format: binary }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'410': { $ref: '#/components/responses/Error' }
|
|
|
|
/shares/{id}/items/{itemId}/frames:
|
|
get:
|
|
tags: [share]
|
|
summary: 下载封存分享中的文件帧
|
|
description: from=0 计一次下载;from>0 只有同一 X-WD-Endpoint 此前对同一文件成功启动过 from=0 才能续传,否则返回 410 gone 且不登记访客。首次成功读取会登记访客终端。
|
|
security: [{ bearer: [] }]
|
|
parameters:
|
|
- { $ref: '#/components/parameters/ShareId' }
|
|
- { $ref: '#/components/parameters/ItemId' }
|
|
- { $ref: '#/components/parameters/Role' }
|
|
- { $ref: '#/components/parameters/Endpoint' }
|
|
- name: from
|
|
in: query
|
|
required: false
|
|
schema: { type: integer, format: int64, minimum: 0, default: 0 }
|
|
responses:
|
|
'200':
|
|
description: 连续封装帧拼接
|
|
content:
|
|
application/octet-stream:
|
|
schema: { type: string, format: binary }
|
|
'403': { $ref: '#/components/responses/Error' }
|
|
'404': { $ref: '#/components/responses/Error' }
|
|
'410': { $ref: '#/components/responses/Error' }
|
|
|
|
components:
|
|
securitySchemes:
|
|
accountBearer:
|
|
type: apiKey
|
|
in: header
|
|
name: X-WD-Account
|
|
description: WebDrop 账号登录后颁发的随机 session token。
|
|
bearer:
|
|
type: http
|
|
scheme: bearer
|
|
description: |
|
|
令牌的 base64url(`T_read` / `T_write` / `T_owner`),与 `X-WD-Role` 配套。
|
|
raw 模式的读请求不需要令牌。
|
|
|
|
parameters:
|
|
ChannelId:
|
|
name: id
|
|
in: path
|
|
required: true
|
|
description: 频道 id,16 字节 base64url
|
|
schema: { $ref: '#/components/schemas/Base64Url' }
|
|
ShareId:
|
|
name: id
|
|
in: path
|
|
required: true
|
|
description: 便捷分享 id,16 字节 base64url
|
|
schema: { $ref: '#/components/schemas/Base64Url' }
|
|
ItemId:
|
|
name: itemId
|
|
in: path
|
|
required: true
|
|
description: 条目 id,16 字节 base64url
|
|
schema: { $ref: '#/components/schemas/Base64Url' }
|
|
Account:
|
|
name: X-WD-Account
|
|
in: header
|
|
required: true
|
|
description: 账号会话令牌。频道与空间只接受已登录账号,缺少或失效返回 401 `account_required`。
|
|
schema: { type: string }
|
|
Role:
|
|
name: X-WD-Role
|
|
in: header
|
|
required: true
|
|
description: 令牌所属角色
|
|
schema: { type: string, enum: [read, write, owner] }
|
|
RoleWriter:
|
|
name: X-WD-Role
|
|
in: header
|
|
required: true
|
|
schema: { type: string, enum: [write, owner] }
|
|
RoleOwner:
|
|
name: X-WD-Role
|
|
in: header
|
|
required: true
|
|
schema: { type: string, enum: [owner] }
|
|
Endpoint:
|
|
name: X-WD-Endpoint
|
|
in: header
|
|
required: false
|
|
description: 终端密钥 `S` 的 base64url,仅存本地。只用于便捷分享(未登录的创建者与读者);频道与空间使用 `X-WD-Account` 会话,不需要它。
|
|
schema: { $ref: '#/components/schemas/Base64Url' }
|
|
ShareEndpoint:
|
|
name: X-WD-Endpoint
|
|
in: header
|
|
required: false
|
|
description: 创建者终端密钥 S 的 base64url,可选,不占访客名额。
|
|
schema: { $ref: '#/components/schemas/Base64Url' }
|
|
Captcha:
|
|
name: X-WD-Cap
|
|
in: header
|
|
required: false
|
|
description: Cap 验证码 token。服务端 `/info` 的 `captcha.enabled` 为 true 时必填;token 一次有效。
|
|
schema: { type: string, maxLength: 2048 }
|
|
|
|
responses:
|
|
Error:
|
|
description: 错误。响应体不回显任何用户提交的内容。
|
|
content:
|
|
application/json:
|
|
schema: { $ref: '#/components/schemas/Error' }
|
|
|
|
schemas:
|
|
AccountChannel:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountChannelBody'
|
|
|
|
AccountDevice:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountDeviceBody'
|
|
|
|
PublicKey:
|
|
$ref: '../contracts/api.schemas.json#/$defs/PublicKeyBody'
|
|
|
|
ChannelInvitation:
|
|
$ref: '../contracts/api.schemas.json#/$defs/InvitationBody'
|
|
|
|
InvitationRequest:
|
|
$ref: '../contracts/api.schemas.json#/$defs/InvitationRequest'
|
|
InvitationCryptoPlan:
|
|
$ref: '../contracts/api.schemas.json#/$defs/InvitationCryptoPlan'
|
|
|
|
ChannelMember:
|
|
$ref: '../contracts/api.schemas.json#/$defs/MemberBody'
|
|
|
|
AccountRegister:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountRegisterRequest'
|
|
|
|
AccountSaltRequest:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountSaltRequest'
|
|
|
|
AccountSalt:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountSaltBody'
|
|
|
|
AccountSessionRequest:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountSessionRequest'
|
|
|
|
AccountSession:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountSessionBody'
|
|
|
|
AccountVault:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AccountVaultBody'
|
|
|
|
Base64Url:
|
|
type: string
|
|
pattern: '^[A-Za-z0-9_-]+$'
|
|
description: base64url,无填充
|
|
|
|
ErrorCode:
|
|
type: string
|
|
enum:
|
|
- bad_request
|
|
- unauthorized
|
|
- forbidden
|
|
- not_joined
|
|
- members_full
|
|
- mode_mismatch
|
|
- not_found
|
|
- conflict
|
|
- gone
|
|
- too_large
|
|
- captcha_required
|
|
- captcha_unavailable
|
|
- rate_limited
|
|
- visitors_full
|
|
- sealed
|
|
- account_required
|
|
- account_invalid
|
|
- invitation_required
|
|
- channel_password_required
|
|
- channel_password_invalid
|
|
- username_unavailable
|
|
- vault_conflict
|
|
|
|
Error:
|
|
type: object
|
|
required: [error]
|
|
properties:
|
|
error: { $ref: '#/components/schemas/ErrorCode' }
|
|
|
|
GoneLog:
|
|
type: object
|
|
required: [error, oldest_seq]
|
|
properties:
|
|
error: { type: string, const: gone }
|
|
oldest_seq: { type: integer, format: int64, description: "清理水位 + 1;0 < from < oldest_seq 的续传需要从 0 全量同步" }
|
|
|
|
ServerInfo:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ServerInfoBody'
|
|
|
|
ChannelMode:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ChannelMode'
|
|
|
|
DeletePolicy:
|
|
$ref: '../contracts/api.schemas.json#/$defs/DeletePolicy'
|
|
|
|
ChannelSettings:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ChannelSettings'
|
|
|
|
ChannelSettingsPatch:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ChannelSettingsPatch'
|
|
|
|
CreateChannelRequest:
|
|
$ref: '../contracts/api.schemas.json#/$defs/CreateChannelRequest'
|
|
|
|
ShareSettings:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ShareSettings'
|
|
|
|
ShareSettingsPatch:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ShareSettingsPatch'
|
|
|
|
CreateShareRequest:
|
|
$ref: '../contracts/api.schemas.json#/$defs/CreateShareRequest'
|
|
|
|
FinishShareRequest:
|
|
$ref: '../contracts/api.schemas.json#/$defs/FinishShareRequest'
|
|
|
|
ShareItemInfo:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ShareItemInfo'
|
|
|
|
ShareInfo:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ShareInfo'
|
|
|
|
ChannelInfo:
|
|
$ref: '../contracts/api.schemas.json#/$defs/ChannelInfo'
|
|
|
|
JoinResult:
|
|
$ref: '../contracts/api.schemas.json#/$defs/JoinResult'
|
|
|
|
AppendResult:
|
|
$ref: '../contracts/api.schemas.json#/$defs/AppendResult'
|