mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 06:06:18 -08:00
fix(server-storage): conditional user-data writes, scoped token, deletes
- User-state entries carry a content tag; PUT/DELETE accept If-Match or If-None-Match: * and answer 412 with the current value and tag. The PWA sends each edit on the tag it read and replays it (before → after) on the server's value after a conflict, so another device's change to the same playlist's favorites or positions is kept instead of overwritten. - The access token goes only to the backend URL (same origin and path), never to another host or a sibling path. - Deleting a playlist (or all) first drops its queued user-data edits and waits for writes in flight, so none recreates deleted data. - The migration copy writes on the tags it read. - The write queue moves out of ServerUserDataStorage into UserDataWriteQueue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f49ad59549
commit
340b1c3efa
18 files changed
+1157
-290
No files matched your search
@@ -58,10 +58,30 @@ export interface ServerStorageStatusResponse {
|
||||
|
||||
export interface ServerUserStateResponse {
|
||||
readonly entries: Record<ServerUserStateNamespace, Record<string, unknown>>;
|
||||
/**
|
||||
* Version tag of every entry. A write sends the tag it is based on
|
||||
* (`If-Match: "<tag>"`, or `If-None-Match: *` for an entry the client
|
||||
* saw absent); a stale tag gets `412` with the current entry.
|
||||
*/
|
||||
readonly tags?: Record<ServerUserStateNamespace, Record<string, string>>;
|
||||
}
|
||||
|
||||
/** Answer to a user-state write: the entry's new tag, `null` once deleted. */
|
||||
export interface ServerUserStateWriteResponse {
|
||||
readonly tag: string | null;
|
||||
}
|
||||
|
||||
/** The entry as the server has it, sent with a `412` conflict. */
|
||||
export interface ServerUserStateCurrent {
|
||||
/** Absent when the entry does not exist. */
|
||||
readonly value?: unknown;
|
||||
readonly tag: string | null;
|
||||
}
|
||||
|
||||
export interface ServerStorageErrorBody {
|
||||
readonly message: string;
|
||||
readonly status: number;
|
||||
readonly code?: string;
|
||||
/** With `code: 'conflict'` (412): the user-state entry as it is now. */
|
||||
readonly current?: ServerUserStateCurrent;
|
||||
}
|
||||
Reference in new issue
Block a user