anchordb-angular 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,70 @@ All notable changes to the `anchordb` packages.
5
5
  This project follows [semantic versioning](https://semver.org/). While the version is `0.x`, minor
6
6
  releases may contain breaking changes.
7
7
 
8
+ ## 1.4.1
9
+
10
+ **Security: `anchordb-sync-server` now keeps users apart.** Up to 1.4.0 the server checked the
11
+ identity `authenticate` returned and then dropped it: every user pulled every user's documents and
12
+ could change or delete any of them by id. Every version before 1.4.1 is affected. Found by the
13
+ expense-tracker team.
14
+
15
+ ### Fixed
16
+
17
+ - **Each document belongs to a scope**, `user:<id>` for the user who created it, and a user reads and
18
+ changes only their own. `authenticate` may return a user id, as before, or
19
+ `{ userId, scopes }` to give a user further scopes (shared books, from 1.5.0).
20
+ - **Refusals reveal nothing.** Someone else's document is answered exactly as one that does not
21
+ exist: `rejected` with `code: 404`.
22
+ - **Retry answers and unique checks are per user.** Remembered answers are keyed by user as well as
23
+ `clientId`, so one user can't read back another's. Unique indexes are checked within the user's
24
+ documents; `{ global: true }` on a unique index checks across everyone (for usernames, say).
25
+ - **Fails closed.** Calling `handlePush`/`handlePull` yourself on a server with `authenticate` and no
26
+ caller is refused with 401. The Express, Next.js and NestJS adapters pass the caller for you.
27
+ - **A server with no `authenticate` warns at startup**, since every caller then shares every
28
+ document. Pass `singleUser: true` if that is what you want; it becomes required in 1.5.0.
29
+
30
+ ### New
31
+
32
+ - **`adoptUnscoped(options, { assignScope })`.** Documents written before 1.4.1 have no scope, and a
33
+ server with `authenticate` hides them from everyone until this one-time command assigns them, for
34
+ example `assignScope: (collection, doc) => doc.userId ? "user:" + doc.userId : null`. Each one it
35
+ assigns is sent to its owner's phones again. It is safe to run twice, and two processes running it
36
+ at once don't assign anything twice. A server that only one person used can assign everything to
37
+ that person: `() => "user:<their id>"`.
38
+ - **Epoch.** Every response carries an `epoch` (default `"2"` with `authenticate`; set `epoch` to
39
+ change it). When a phone sees a new one, it deletes its synced copy and pulls again, keeping its
40
+ unsent changes (`sync:reset` event). That clears out other users' documents that phones pulled from
41
+ 1.4.0 servers.
42
+ - **Protocol version 2.** A server with `authenticate` answers phones built with an older anchordb
43
+ `426 Update the app`, since they ignore the epoch. `legacyClients: "allow"` serves them for a
44
+ transition period. They are still kept apart, but they keep whatever they already pulled.
45
+ - **Pull limit** capped at 1000 changes (`maxPullLimit`).
46
+ - **Each pulled change carries its `scope`**, and the phone records it with the document.
47
+
48
+ ### Changed on the phone (`anchordb`)
49
+
50
+ - A change refused with 404 is parked, as before, and the phone now also deletes its copy of that
51
+ document — so another user's document that was edited offline doesn't stay on the phone. A
52
+ refused insert keeps the user's new document.
53
+ - **A document deleted on the user's other phone** now comes back as a conflict marked
54
+ `deleted: true` with `document: null`, and goes through the conflict strategy: `server-wins`
55
+ accepts the delete; `last-write-wins` keeps a newer local edit and brings the document back;
56
+ `client-wins` always brings it back; `field-level` falls back to last-write-wins. A custom
57
+ `resolver` receives `remote: null`, and returns null to accept the delete. The `conflict` event
58
+ gains `remoteDeleted` and `resolvedDeleted`.
59
+
60
+ ### Upgrading — in this order
61
+
62
+ 1. **Upgrade the server** to `anchordb-sync-server@1.4.1`.
63
+ 2. **Run `adoptUnscoped`** once with an `assignScope` that knows whose each document is. Until you
64
+ do, those documents are hidden from everyone. Nothing is ever deleted on the server.
65
+ 3. **Ship a new app build** with `anchordb@1.4.1`. On its first sync it starts over once, because of
66
+ the new epoch, and its unsent changes are kept.
67
+
68
+ App builds that use an anchordb version before 1.4.1 **stop syncing** (426) until users install the
69
+ update, unless the server sets `legacyClients: "allow"`. A server without `authenticate` is unchanged:
70
+ it still serves everyone everything, and still accepts old phones.
71
+
8
72
  ## 1.4.0
9
73
 
10
74
  **Transactions, migrations, recovery, TTL indexes, encryption, a test kit — and guides that ship in the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anchordb-angular",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "@capacitor-community/sqlite": ">=6",
37
37
  "@capacitor/core": ">=6",
38
- "anchordb": "^1.4.0"
38
+ "anchordb": "^1.4.1"
39
39
  },
40
40
  "devDependencies": {
41
41
  "rimraf": "^6.0.1"