Jak to działa

Od startu na orbitę

Krok po kroku: administrator zakłada tenanta MindooDB, dwóch użytkowników wymienia zaszyfrowane dane i pracuje razem — a serwer ani razu nie widzi tekstu jawnego.

01

Start

Administrator uruchamia tenanta

1
Administrator i Alice

Utwórz tenanta

Administrator zakłada nowego tenanta jednym wywołaniem. Powstają przy tym wszystkie klucze, tenant zostaje otwarty, a pierwszy użytkownik — Alice — zarejestrowany w katalogu.

const { tenant, adminUser, appUser, keyBag }
  = await factory.createTenant({
    tenantId: "acme",
    adminName: "cn=admin/o=acme",
    adminPassword: "••••••••",
    userName: "cn=alice/o=acme",
    userPassword: "••••••••",
  });
2
Administrator i Alice

Opublikuj na serwerze

Administrator rejestruje tenanta na serwerze MindooDB. Serwer przechowuje tylko zaszyfrowane dane i klucze publiczne.

await tenant.publishToServer(
  "https://sync.acme.com",
  { registerUsers: [appUser] }
);
🔒 register-tenant
Serwer nigdy nie otrzymuje klucza tenanta
3
Administrator i Alice

Utwórz i zsynchronizuj dokument

Alice zakłada dokument z zadaniem i wypycha zaszyfrowane zmiany na serwer.

const db = await tenant.openDB("todos");
const doc = await db.createDocument();
await db.changeDoc(doc, (d) => {
  const data = d.getData();
  data.title = "Buy groceries";
  data.done = false;
});

const remote = await tenant.connectToServer(
  "https://sync.acme.com", "todos"
);
await db.pushChangesTo(remote);
02

Sygnał

Nowy użytkownik prosi o dołączenie

4
Bob

Utwórz prośbę o dołączenie

Bob tworzy swoją tożsamość lokalnie — jego klucze prywatne nigdy nie opuszczają urządzenia. Generuje prośbę o dołączenie, która zawiera wyłącznie klucze publiczne.

const bob = await factory.createUserId(
  "cn=bob/o=acme", "••••••••"
);

const joinRequestURI = factory.createJoinRequest(
  bob, { format: "uri" }
);
// → mdb://join-request/eyJ2IjoxLCJ1c2Vy...
mdb://join-request/...
Tylko klucze publiczne — można je przesłać dowolnym kanałem
03

Dokowanie

Administrator zatwierdza prośbę o dołączenie

5
Administrator i Alice

Zatwierdź prośbę o dołączenie

Administrator zatwierdza prośbę Boba. Bob zostaje przez to zarejestrowany w katalogu, a klucze symetryczne zaszyfrowane wspólnym hasłem.

const joinResponseURI =
  await tenant.approveJoinRequest(
    joinRequestURI,
    {
      adminSigningKey: adminUser
        .userSigningKeyPair.privateKey,
      adminPassword: "••••••••",
      sharePassword: "one-time-secret",
      format: "uri",
    }
  );
// → mdb://join-response/eyJ2IjoxLCJ0ZW5h...
🔒 mdb://join-response/...
Wspólne hasło przekaż drugim kanałem: telefonicznie albo osobiście
04

Orbita

Zaczyna się współpraca w czasie rzeczywistym

6
Bob

Dołącz, pobierz, zmień, wypchnij

Bob dołącza do tenanta, pobiera najnowsze dane, oznacza zadanie jako zrobione i wypycha zmianę z powrotem.

const { tenant: bobTenant } =
  await factory.joinTenant(
    joinResponseURI,
    {
      user: bob,
      password: "••••••••",
      sharePassword: "one-time-secret",
    }
  );

const remote = await bobTenant.connectToServer(
  "https://sync.acme.com", "todos"
);
const db = await bobTenant.openDB("todos");
await db.pullChangesFrom(remote);
await db.syncStoreChanges();

const todo = await db.getDocument(todoDocId);
await db.changeDoc(todo, (d) => {
  d.getData().done = true;
});
await db.pushChangesTo(remote);
7
Administrator i Alice

Pobierz zmiany

Alice pobiera najnowsze zmiany i widzi, że zadanie jest zrobione.

await db.pullChangesFrom(remote);
await db.syncStoreChanges();

const updated = await db.getDocument(todoDocId);
console.log(updated.getData().done);
// → true ✓
Zadanie zrobione ✓

Co serwer widzi, a czego nie

Serwer widzi

  • Publiczne klucze podpisujące (Ed25519)
  • Publiczne klucze szyfrujące (RSA-OAEP)
  • Zaszyfrowane bloby (szyfrogram AES-256-GCM)
  • Metadane wpisów (znaczniki czasu, skróty treści)
  • Hashe nazw użytkowników (SHA-256 — nie same nazwy)

Serwer nie widzi nigdy

  • Nazw użytkowników (szyfrowanych kluczem RSA administratora)
  • Treści dokumentów (szyfrowanych end-to-end)
  • Kluczy prywatnych (zostają na urządzeniu)
  • Wspólnych haseł (tylko poza pasmem)
  • Symetrycznych kluczy szyfrujących
Pierwsze kroki Architektura w szczegółach