Initial commit

This commit is contained in:
2026-04-08 11:55:27 +01:00
commit 470a1c15b8
36 changed files with 4932 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
import assert from "node:assert/strict";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import test from "node:test";
import { createFileSyncStore } from "../../apps/sync-server/src/store/fileSyncStore";
test("file-backed store survives restart and serves another device", () => {
const tempDirectory = mkdtempSync(path.join(tmpdir(), "obsidian-sync-"));
const storePath = path.join(tempDirectory, "sync-state.json");
try {
const serverA = createFileSyncStore(storePath);
const deviceA = serverA.registerDevice({
vaultId: "vault-1",
deviceName: "Desktop"
});
const deviceB = serverA.registerDevice({
vaultId: "vault-1",
deviceName: "Phone"
});
const pushResponse = serverA.push({
vaultId: "vault-1",
deviceId: deviceA.deviceId,
knownServerRevision: 0,
files: [
{
manifest: {
path: "notes/hello.md",
kind: "text",
contentHash: "hash-1",
revisionId: "rev-1",
updatedAt: "2026-04-08T00:00:00.000Z",
sizeBytes: 12,
deviceId: deviceA.deviceId
},
envelope: {
algorithm: "AES-GCM-256",
keyId: "key-1",
iv: "iv-1",
ciphertext: "cipher-1"
}
}
],
tombstones: []
});
assert.deepEqual(pushResponse.acceptedFilePaths, ["notes/hello.md"]);
const serverB = createFileSyncStore(storePath);
assert.equal(serverB.authenticate("vault-1", deviceB.deviceId, deviceB.token), true);
const pullResponse = serverB.pull("vault-1", 0);
assert.equal(pullResponse.changes.length, 1);
assert.equal(pullResponse.changes[0].file?.manifest.path, "notes/hello.md");
assert.equal(pullResponse.serverRevision, 1);
assert.equal(pullResponse.hasMore, false);
assert.equal(pullResponse.nextSinceServerRevision, 1);
} finally {
rmSync(tempDirectory, { recursive: true, force: true });
}
});
test("file-backed store paginates pull results", () => {
const tempDirectory = mkdtempSync(path.join(tmpdir(), "obsidian-sync-page-"));
const storePath = path.join(tempDirectory, "sync-state.json");
try {
const store = createFileSyncStore(storePath);
const device = store.registerDevice({
vaultId: "vault-2",
deviceName: "Desktop"
});
store.push({
vaultId: "vault-2",
deviceId: device.deviceId,
knownServerRevision: 0,
files: [
{
manifest: {
path: "a.md",
kind: "text",
contentHash: "hash-a",
revisionId: "rev-a",
updatedAt: "2026-04-08T00:00:00.000Z",
sizeBytes: 1,
deviceId: device.deviceId
},
envelope: {
algorithm: "AES-GCM-256",
keyId: "key-a",
iv: "iv-a",
ciphertext: "cipher-a"
}
}
],
tombstones: []
});
store.push({
vaultId: "vault-2",
deviceId: device.deviceId,
knownServerRevision: 1,
files: [
{
manifest: {
path: "b.md",
kind: "text",
contentHash: "hash-b",
revisionId: "rev-b",
updatedAt: "2026-04-08T00:01:00.000Z",
sizeBytes: 1,
deviceId: device.deviceId
},
envelope: {
algorithm: "AES-GCM-256",
keyId: "key-a",
iv: "iv-b",
ciphertext: "cipher-b"
}
}
],
tombstones: []
});
const firstPage = store.pull("vault-2", 0, 1);
assert.equal(firstPage.changes.length, 1);
assert.equal(firstPage.hasMore, true);
assert.equal(firstPage.nextSinceServerRevision, 1);
const secondPage = store.pull("vault-2", firstPage.nextSinceServerRevision, 1);
assert.equal(secondPage.changes.length, 1);
assert.equal(secondPage.hasMore, false);
assert.equal(secondPage.nextSinceServerRevision, 2);
assert.equal(secondPage.changes[0].file?.manifest.path, "b.md");
} finally {
rmSync(tempDirectory, { recursive: true, force: true });
}
});
test("device revocation and key rotation state are durable", () => {
const tempDirectory = mkdtempSync(path.join(tmpdir(), "obsidian-sync-device-"));
const storePath = path.join(tempDirectory, "sync-state.json");
try {
const store = createFileSyncStore(storePath);
const desktop = store.registerDevice({
vaultId: "vault-3",
deviceName: "Desktop"
});
const phone = store.registerDevice({
vaultId: "vault-3",
deviceName: "Phone"
});
const rotation = store.rotateVaultKey("vault-3", "key-rotated");
assert.equal(rotation.activeKeyId, "key-rotated");
const revoked = store.revokeDevice("vault-3", phone.deviceId);
assert.equal(revoked.targetDeviceId, phone.deviceId);
assert.equal(store.authenticate("vault-3", phone.deviceId, phone.token), false);
const restartedStore = createFileSyncStore(storePath);
const devices = restartedStore.listDevices("vault-3");
assert.equal(devices.activeKeyId, "key-rotated");
assert.equal(devices.devices.find((device) => device.deviceId === phone.deviceId)?.revokedAt !== undefined, true);
assert.equal(restartedStore.authenticate("vault-3", desktop.deviceId, desktop.token), true);
} finally {
rmSync(tempDirectory, { recursive: true, force: true });
}
});