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
@@ -1,5 +1,5 @@
|
||||
// Generated from backend DTOs; do not edit.
|
||||
// backend-contract-sha256: ba787115471d5d33fb0c33c95af014b5cd0d535455bd4bea037cfdcc4f048828
|
||||
// backend-contract-sha256: 54ea3f00fa672e0241efbb9fc8e7ad9e8fc68415ec124e08f70657c2d57d9ff9
|
||||
|
||||
export interface AccountChannelBody {
|
||||
channel_id: string;
|
||||
@@ -79,10 +79,10 @@ export interface ChannelInfo {
|
||||
expires_at: number;
|
||||
id: string;
|
||||
last_seq: number;
|
||||
members_used: number;
|
||||
mode: ChannelMode;
|
||||
oldest_seq: number;
|
||||
password_required: boolean;
|
||||
seats_used: number;
|
||||
settings: ChannelSettings;
|
||||
}
|
||||
export type ChannelMode = 'enc' | 'raw';
|
||||
@@ -93,9 +93,9 @@ export interface ChannelSettings {
|
||||
file_max_downloads: number;
|
||||
join_policy: JoinPolicy;
|
||||
max_items: number;
|
||||
max_members: number;
|
||||
members_can_upload: boolean;
|
||||
name?: string | null;
|
||||
seats: number;
|
||||
ttl_seconds: number;
|
||||
ui_restrict_copy_download: boolean;
|
||||
}
|
||||
@@ -106,9 +106,9 @@ export interface ChannelSettingsPatch {
|
||||
join_password?: string | null;
|
||||
join_policy?: JoinPolicy | null;
|
||||
max_items?: number | null;
|
||||
max_members?: number | null;
|
||||
members_can_upload?: boolean | null;
|
||||
name?: string | null;
|
||||
seats?: number | null;
|
||||
ttl_seconds?: number | null;
|
||||
ui_restrict_copy_download?: boolean | null;
|
||||
}
|
||||
@@ -171,6 +171,10 @@ export interface GoneLogBody {
|
||||
error: string;
|
||||
oldest_seq: number;
|
||||
}
|
||||
export interface GuestInfo {
|
||||
endpoint_hash: string;
|
||||
joined_at: number;
|
||||
}
|
||||
export interface InvitationBody {
|
||||
channel_id: string;
|
||||
created_at: number;
|
||||
@@ -198,11 +202,19 @@ export type JoinPolicy = 'open' | 'invite';
|
||||
export interface JoinRequest {
|
||||
password?: string | null;
|
||||
}
|
||||
export interface JoinResult {
|
||||
joined_at: number;
|
||||
members_max: number;
|
||||
members_used: number;
|
||||
}
|
||||
export interface KeyPackageRequest {
|
||||
payload: string;
|
||||
}
|
||||
export interface MemberBody {
|
||||
devices: number;
|
||||
joined_at: number;
|
||||
online: boolean;
|
||||
online_devices: number;
|
||||
role: string;
|
||||
username: string;
|
||||
}
|
||||
@@ -260,18 +272,6 @@ export interface PublicKeyBody {
|
||||
public_key: string;
|
||||
signing_public_key?: string | null;
|
||||
}
|
||||
export interface SeatInfo {
|
||||
account_name?: string | null;
|
||||
endpoint_hash: string;
|
||||
joined_at: number;
|
||||
label?: string | null;
|
||||
}
|
||||
export interface SeatJoined {
|
||||
endpoint_hash: string;
|
||||
joined_at: number;
|
||||
seats_max: number;
|
||||
seats_used: number;
|
||||
}
|
||||
export interface ServerInfoBody {
|
||||
captcha: CaptchaBody;
|
||||
choices: SettingChoicesBody;
|
||||
@@ -295,8 +295,8 @@ export interface LimitsBody {
|
||||
max_channel_bytes: number;
|
||||
max_frames_per_item: number;
|
||||
max_items: number;
|
||||
max_members: number;
|
||||
max_payload_bytes: number;
|
||||
max_seats: number;
|
||||
max_ttl_seconds: number;
|
||||
max_visitors: number;
|
||||
max_workspace_bytes: number;
|
||||
@@ -305,8 +305,8 @@ export interface LimitsBody {
|
||||
}
|
||||
export interface SettingChoicesBody {
|
||||
file_max_downloads: number[];
|
||||
max_members: number[];
|
||||
max_visitors: number[];
|
||||
seats: number[];
|
||||
ttl_seconds: number[];
|
||||
}
|
||||
export interface ShareInfo {
|
||||
|
||||
Reference in new issue
Block a user