88 Entropy32 ,
99 RandomBytesDep ,
1010} from "../Crypto.js" ;
11+ import { getOrNull } from "../Result.js" ;
1112import {
1213 brand ,
1314 Id ,
@@ -16,12 +17,9 @@ import {
1617 idToIdBytes ,
1718 Mnemonic ,
1819 NonNegativeInt ,
19- PositiveInt ,
2020} from "../Type.js" ;
21- import { getOrNull } from "../Result.js" ;
22- import type { Timestamp } from "./Timestamp.js" ;
23- import { TimestampBytes } from "./Timestamp.js" ;
2421import type { Storage } from "./Storage.js" ;
22+ import type { Timestamp , TimestampBytes } from "./Timestamp.js" ;
2523
2624/**
2725 * The Owner represents ownership of data in Evolu. Every database change is
@@ -159,6 +157,17 @@ export const createOwner = (secret: OwnerSecret): Owner => ({
159157 * preserved because it coordinates deletion information across devices. Other
160158 * devices need to sync the information that an owner was deleted so they can
161159 * delete their local data as well.
160+ *
161+ * ### Privacy Considerations
162+ *
163+ * AppOwner must never be shared with anyone, except for its {@link OwnerId},
164+ * which can be used for authorization with
165+ * {@link createOwnerWebSocketTransport}. It's safe because OwnerId is
166+ * pseudonymous (it can't be assigned to a specific person).
167+ *
168+ * For data sharing scenarios, use {@link SharedOwner} and
169+ * {@link SharedReadonlyOwner} instead, which are designed specifically for
170+ * collaborative access.
162171 */
163172export interface AppOwner extends Owner {
164173 readonly type : "AppOwner" ;
@@ -294,7 +303,17 @@ export type OwnerTransport = OwnerWebSocketTransport;
294303/**
295304 * WebSocket transport configuration.
296305 *
297- * ### Authentication and Error Handling
306+ * ### Authentication via URL
307+ *
308+ * The {@link OwnerId} is passed as a URL query parameter. While this approach is
309+ * generally discouraged for authentication tokens (they get logged), it's safe
310+ * here because OwnerId is pseudonymous and used only for access verification -
311+ * it provides no ability to read encrypted data or write changes.
312+ *
313+ * See: [HTTP headers in Websockets client
314+ * API](https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api/74564827#74564827)
315+ *
316+ * ### Error Handling
298317 *
299318 * When a relay rejects a connection (invalid OwnerId, unauthorized owner, or
300319 * server error), the browser WebSocket API does not expose the specific HTTP
@@ -317,6 +336,10 @@ export interface OwnerWebSocketTransport {
317336 * Creates an {@link OwnerWebSocketTransport} for the given relay URL and
318337 * {@link OwnerId}.
319338 *
339+ * The URL must be a WebSocket base URL without query parameters or fragments
340+ * (e.g., `wss://relay.evolu.dev`, not `wss://relay.evolu.dev?foo=bar`). The
341+ * function appends the `ownerId` as a query parameter.
342+ *
320343 * ### Example
321344 *
322345 * ```ts
@@ -369,13 +392,13 @@ export interface OwnerUsage {
369392 readonly ownerId : OwnerIdBytes ;
370393
371394 /** Total bytes stored in the database. */
372- readonly storedBytes : PositiveInt ;
395+ readonly storedBytes : NonNegativeInt ;
373396
374397 /** Total bytes received. */
375- readonly receivedBytes : number ;
398+ readonly receivedBytes : NonNegativeInt ;
376399
377400 /** Total bytes sent. */
378- readonly sentBytes : number ;
401+ readonly sentBytes : NonNegativeInt ;
379402
380403 /**
381404 * The minimum {@link Timestamp}.
0 commit comments