feat(api)!: fold devices into users and report member presence
Contract 7.0.0 (breaking). Devices become an attribute of the account;
members are managed per user, and only unauthenticated guests keep a
per-terminal registration.
- rename seats -> max_members, seats_used -> members_used,
seats_full -> members_full, SeatJoined -> JoinResult, the `seats`
stream control message -> `members`, and POST /channels/{id}/seats ->
POST /channels/{id}/join (stored channel settings are migrated on start)
- drop per-terminal encrypted device labels and the seat list/release
endpoints; add GET/DELETE /channels/{id}/guests for guest terminals
- authenticate account members by account session only: the terminal key
is optional for logged-in accounts, no seat row is written for them,
and gated-download grants are counted per user (per terminal for guests)
- GET /channels/{id}/members now returns online, devices and
online_devices per account; presence is tracked in memory from active
WebSocket/SSE subscriptions and is not pushed over the stream
- owner invitation list no longer returns accounts that already joined
This commit is contained in:
1 parent
0fd2a269d9
commit
d946fc5e8a
35 files changed
+517
-490
No files matched your search
@@ -82,7 +82,8 @@ public sealed record Item(
|
||||
public bool IsComplete => FinalIndex is { } f && FrameCount == f + 1;
|
||||
}
|
||||
|
||||
public sealed record Seat(byte[] EndpointHash, long JoinedAt, byte[]? Label, string? AccountName = null, string? AccountDeviceId = null);
|
||||
/// <summary>频道内的终端登记(账号设备或访客终端)。设备只是账号的属性,不是成员;不再有单独的设备名。</summary>
|
||||
public sealed record Seat(byte[] EndpointHash, long JoinedAt, string? AccountName = null, string? AccountDeviceId = null);
|
||||
public sealed record ChannelInvitation(Id16 ChannelId, string Username, string Payload, long CreatedAt);
|
||||
public sealed record ChannelMember(string Username, string Role, long JoinedAt);
|
||||
public sealed record ChannelKeyPackage(Id16 ChannelId, string Username, string Role, string Payload, long CreatedAt);
|
||||
@@ -101,7 +102,13 @@ public sealed record StoredFrame(
|
||||
public sealed record LogEntry(long Seq, LogKind Kind, Id16 ItemId, uint FrameIndex, byte Aux, long CreatedAt);
|
||||
|
||||
/// <summary>一次请求验证通过后的身份。</summary>
|
||||
public sealed record Principal(Role Role, byte[] EndpointHash, string? AccountName = null);
|
||||
public sealed record Principal(Role Role, byte[] EndpointHash, string? AccountName = null)
|
||||
{
|
||||
/// <summary>受限下载的计数单位:账号按用户计(设备只是账号的属性),访客按终端计。</summary>
|
||||
public byte[] GrantKey => AccountName is null
|
||||
? EndpointHash
|
||||
: System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes("webdrop/grant/v1/" + AccountName));
|
||||
}
|
||||
|
||||
/// <summary>请求携带的凭据,尚未验证。</summary>
|
||||
public sealed record Credentials(Role ClaimedRole, byte[]? Token, byte[] EndpointHash, string? AccountName = null, string? AccountDeviceId = null,
|
||||
|
||||
Reference in new issue
Block a user