refactor(host): single-source ChannelPolicy, space-signed file grants, whole-file registration

- all authorization rules (owner/creator, per-channel read/write grants, who may
  remove whom, delete rules, structure management) live in ChannelPolicy; a test
  fails if they are reimplemented elsewhere
- ChannelInfo carries what the caller may do (can_*), member and invitation lists
  say who can be removed; clients display it and never derive it
- the host no longer stores or calls the file service: it only signs short-lived
  tickets from space permissions (create/put/get/delete/domain), and keeps an opaque
  fileDomain reference on the channel
- a whole file is registered in one request (last frame header + per-frame length and
  digest) instead of one request per 1 MiB frame; the signed manifest still has to
  match every digest
- drop file quota/threshold, receipts, reconcile and delete-queue code from the host
- contract generator emits constants for enums, error codes, token roles, permissions
  and share states
This commit is contained in:
justme committed 2026-10-19 13:38:40 +08:00
1 parent ccb2c074d6
commit 17638b6e20
36 files changed
+926 -589

No files matched your search

+101 -30
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"x-backend-contract-sha256": "6e4037d39ac5ae791724731810e3df5b791839e8ab29cf54643ec1a294132964",
"x-backend-contract-sha256": "340876061d7b324e4fd16972e276ffb0f238eeac66b214a043b3b4b98d560fcf",
"$defs": {
"AccountChannelBody": {
"type": "object",
@@ -322,9 +322,33 @@
}
]
},
"can_create_channel": {
"type": "boolean"
},
"can_delete_any": {
"type": "boolean"
},
"can_delete_own": {
"type": "boolean"
},
"can_edit_settings": {
"type": "boolean"
},
"can_invite": {
"type": "boolean"
},
"can_manage_folders": {
"type": "boolean"
},
"can_manage_roles": {
"type": "boolean"
},
"can_manage_structure": {
"type": "boolean"
},
"can_remove_members": {
"type": "boolean"
},
"can_upload": {
"type": "boolean"
},
@@ -347,6 +371,9 @@
"id": {
"type": "string"
},
"is_owner": {
"type": "boolean"
},
"last_seq": {
"type": "integer"
},
@@ -367,11 +394,20 @@
}
},
"required": [
"can_create_channel",
"can_delete_any",
"can_delete_own",
"can_edit_settings",
"can_invite",
"can_manage_folders",
"can_manage_roles",
"can_manage_structure",
"can_remove_members",
"can_upload",
"created_at",
"expires_at",
"id",
"is_owner",
"last_seq",
"members_used",
"mode",
@@ -847,46 +883,51 @@
"FileGrantBody": {
"type": "object",
"properties": {
"domain": {
"type": "string"
},
"expires_at": {
"type": "integer"
},
"mode": {
"ticket": {
"type": "string"
},
"ticket": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
"type": "string"
}
},
"required": [
"domain",
"expires_at",
"mode"
"ticket",
"url"
]
},
"FileGrantRequest": {
"type": "object",
"properties": {
"channel": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"from": {
"type": "integer"
},
"item": {
"type": "string"
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"op": {
"type": "string"
@@ -894,7 +935,6 @@
},
"required": [
"from",
"item",
"op"
]
},
@@ -932,6 +972,9 @@
"InvitationBody": {
"type": "object",
"properties": {
"can_revoke": {
"type": "boolean"
},
"channel_id": {
"type": "string"
},
@@ -946,6 +989,7 @@
}
},
"required": [
"can_revoke",
"channel_id",
"created_at",
"payload",
@@ -1084,6 +1128,9 @@
"MemberBody": {
"type": "object",
"properties": {
"can_remove": {
"type": "boolean"
},
"devices": {
"type": "integer"
},
@@ -1107,6 +1154,7 @@
}
},
"required": [
"can_remove",
"devices",
"joined_at",
"last_seen",
@@ -1524,9 +1572,6 @@
"max_workspace_bytes": {
"type": "integer"
},
"max_workspace_channel_bytes": {
"type": "integer"
},
"min_ttl_seconds": {
"type": "integer"
}
@@ -1540,7 +1585,6 @@
"max_ttl_seconds",
"max_visitors",
"max_workspace_bytes",
"max_workspace_channel_bytes",
"min_ttl_seconds"
]
},
@@ -1856,8 +1900,15 @@
"createdBy": {
"type": "string"
},
"fileBytes": {
"type": "integer"
"fileDomain": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"filesEpoch": {
"type": "integer"
@@ -1887,7 +1938,6 @@
"chatHistory",
"createdAt",
"createdBy",
"fileBytes",
"filesEpoch",
"filesHistory",
"id",
@@ -1897,6 +1947,16 @@
"WorkspaceChannelRequest": {
"type": "object",
"properties": {
"fileDomain": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"groupId": {
"anyOf": [
{
@@ -1915,6 +1975,17 @@
"name"
]
},
"WorkspaceFileDomainRequest": {
"type": "object",
"properties": {
"fileDomain": {
"type": "string"
}
},
"required": [
"fileDomain"
]
},
"WorkspaceFolderRequest": {
"type": "object",
"properties": {