Skip to content

Commit b232d85

Browse files
committed
Update OwnerUsage types and add privacy documentation
1 parent b2a91d2 commit b232d85

1 file changed

Lines changed: 31 additions & 8 deletions

File tree

packages/common/src/Evolu/Owner.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Entropy32,
99
RandomBytesDep,
1010
} from "../Crypto.js";
11+
import { getOrNull } from "../Result.js";
1112
import {
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";
2421
import 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
*/
163172
export 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

Comments
 (0)