mindoodb 0.0.3 → 0.0.5
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.
- package/README-server.md +1030 -0
- package/README.md +14 -26
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +27 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +270 -121
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.d.ts +15 -0
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.js +235 -10
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +5 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +40 -4
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +10 -3
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +138 -13
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -1
- package/dist/browser/cache/IndexedDBLocalCacheStore.d.ts +21 -0
- package/dist/browser/cache/IndexedDBLocalCacheStore.d.ts.map +1 -0
- package/dist/browser/cache/IndexedDBLocalCacheStore.js +106 -0
- package/dist/browser/cache/IndexedDBLocalCacheStore.js.map +1 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +9 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/core/BaseMindooDB.d.ts +108 -13
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +1268 -292
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +31 -1
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +212 -129
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts +13 -10
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +134 -27
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/BaseMindooTenantFactory.d.ts +5 -1
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantFactory.js +46 -69
- package/dist/core/BaseMindooTenantFactory.js.map +1 -1
- package/dist/core/MindooDBServerAdmin.d.ts +241 -0
- package/dist/core/MindooDBServerAdmin.d.ts.map +1 -0
- package/dist/core/MindooDBServerAdmin.js +401 -0
- package/dist/core/MindooDBServerAdmin.js.map +1 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.d.ts +22 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.d.ts.map +1 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.js +124 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.js.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +10 -4
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +44 -9
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/MaterializationPlanner.d.ts +84 -0
- package/dist/core/appendonlystores/MaterializationPlanner.d.ts.map +1 -0
- package/dist/core/appendonlystores/MaterializationPlanner.js +326 -0
- package/dist/core/appendonlystores/MaterializationPlanner.js.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts +33 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.d.ts +35 -0
- package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.js +2 -0
- package/dist/core/appendonlystores/network/types.js.map +1 -1
- package/dist/core/appendonlystores/types.d.ts +174 -3
- package/dist/core/appendonlystores/types.d.ts.map +1 -1
- package/dist/core/cache/CacheManager.d.ts +75 -0
- package/dist/core/cache/CacheManager.d.ts.map +1 -0
- package/dist/core/cache/CacheManager.js +101 -0
- package/dist/core/cache/CacheManager.js.map +1 -0
- package/dist/core/cache/EncryptedLocalCacheStore.d.ts +41 -0
- package/dist/core/cache/EncryptedLocalCacheStore.d.ts.map +1 -0
- package/dist/core/cache/EncryptedLocalCacheStore.js +120 -0
- package/dist/core/cache/EncryptedLocalCacheStore.js.map +1 -0
- package/dist/core/cache/LocalCacheStore.d.ts +50 -0
- package/dist/core/cache/LocalCacheStore.d.ts.map +1 -0
- package/dist/core/cache/LocalCacheStore.js +39 -0
- package/dist/core/cache/LocalCacheStore.js.map +1 -0
- package/dist/core/crypto/privateKeyEncryption.d.ts +5 -0
- package/dist/core/crypto/privateKeyEncryption.d.ts.map +1 -0
- package/dist/core/crypto/privateKeyEncryption.js +87 -0
- package/dist/core/crypto/privateKeyEncryption.js.map +1 -0
- package/dist/core/index.d.ts +13 -6
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +13 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +4 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +39 -11
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js +3 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.d.ts +43 -0
- package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.js +173 -0
- package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +7 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +28 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -1
- package/dist/core/keys/KeyBag.d.ts +38 -14
- package/dist/core/keys/KeyBag.d.ts.map +1 -1
- package/dist/core/keys/KeyBag.js +102 -76
- package/dist/core/keys/KeyBag.js.map +1 -1
- package/dist/core/keys/KeyContext.d.ts +3 -3
- package/dist/core/keys/KeyContext.d.ts.map +1 -1
- package/dist/core/keys/KeyContext.js +10 -4
- package/dist/core/keys/KeyContext.js.map +1 -1
- package/dist/core/types.d.ts +341 -22
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +7 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/idGeneration.d.ts.map +1 -1
- package/dist/core/utils/idGeneration.js +37 -3
- package/dist/core/utils/idGeneration.js.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +31 -7
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +139 -17
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -1
- package/dist/node/attachments/writeAttachmentToFile.d.ts +15 -0
- package/dist/node/attachments/writeAttachmentToFile.d.ts.map +1 -0
- package/dist/node/attachments/writeAttachmentToFile.js +73 -0
- package/dist/node/attachments/writeAttachmentToFile.js.map +1 -0
- package/dist/node/cache/FileSystemLocalCacheStore.d.ts +17 -0
- package/dist/node/cache/FileSystemLocalCacheStore.d.ts.map +1 -0
- package/dist/node/cache/FileSystemLocalCacheStore.js +128 -0
- package/dist/node/cache/FileSystemLocalCacheStore.js.map +1 -0
- package/dist/node/cli/change-identity-password.d.ts +7 -0
- package/dist/node/cli/change-identity-password.d.ts.map +1 -0
- package/dist/node/cli/change-identity-password.js +67 -0
- package/dist/node/cli/change-identity-password.js.map +1 -0
- package/dist/node/cli/cli-utils.d.ts +16 -0
- package/dist/node/cli/cli-utils.d.ts.map +1 -0
- package/dist/node/cli/cli-utils.js +113 -0
- package/dist/node/cli/cli-utils.js.map +1 -0
- package/dist/node/cli/identity-export-public.d.ts +4 -0
- package/dist/node/cli/identity-export-public.d.ts.map +1 -0
- package/dist/node/cli/identity-export-public.js +55 -0
- package/dist/node/cli/identity-export-public.js.map +1 -0
- package/dist/node/cli/identity-info.d.ts +4 -0
- package/dist/node/cli/identity-info.d.ts.map +1 -0
- package/dist/node/cli/identity-info.js +57 -0
- package/dist/node/cli/identity-info.js.map +1 -0
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +4 -1
- package/dist/node/index.js.map +1 -1
- package/dist/node/server/CapabilityMatcher.d.ts +45 -0
- package/dist/node/server/CapabilityMatcher.d.ts.map +1 -0
- package/dist/node/server/CapabilityMatcher.js +117 -0
- package/dist/node/server/CapabilityMatcher.js.map +1 -0
- package/dist/node/server/MindooDBServer.d.ts +94 -0
- package/dist/node/server/MindooDBServer.d.ts.map +1 -0
- package/dist/node/server/MindooDBServer.js +1256 -0
- package/dist/node/server/MindooDBServer.js.map +1 -0
- package/dist/node/server/ServerSync.d.ts +41 -0
- package/dist/node/server/ServerSync.d.ts.map +1 -0
- package/dist/node/server/ServerSync.js +187 -0
- package/dist/node/server/ServerSync.js.map +1 -0
- package/dist/node/server/StoreFactory.d.ts +45 -0
- package/dist/node/server/StoreFactory.d.ts.map +1 -0
- package/dist/node/server/StoreFactory.js +89 -0
- package/dist/node/server/StoreFactory.js.map +1 -0
- package/dist/node/server/SystemAdminAuth.d.ts +65 -0
- package/dist/node/server/SystemAdminAuth.d.ts.map +1 -0
- package/dist/node/server/SystemAdminAuth.js +200 -0
- package/dist/node/server/SystemAdminAuth.js.map +1 -0
- package/dist/node/server/SystemIpAllowlist.d.ts +21 -0
- package/dist/node/server/SystemIpAllowlist.d.ts.map +1 -0
- package/dist/node/server/SystemIpAllowlist.js +210 -0
- package/dist/node/server/SystemIpAllowlist.js.map +1 -0
- package/dist/node/server/TenantManager.d.ts +100 -0
- package/dist/node/server/TenantManager.d.ts.map +1 -0
- package/dist/node/server/TenantManager.js +615 -0
- package/dist/node/server/TenantManager.js.map +1 -0
- package/dist/node/server/add-to-network.d.ts +20 -0
- package/dist/node/server/add-to-network.d.ts.map +1 -0
- package/dist/node/server/add-to-network.js +275 -0
- package/dist/node/server/add-to-network.js.map +1 -0
- package/dist/node/server/config.d.ts +51 -0
- package/dist/node/server/config.d.ts.map +1 -0
- package/dist/node/server/config.js +218 -0
- package/dist/node/server/config.js.map +1 -0
- package/dist/node/server/resolveServerPassword.d.ts +7 -0
- package/dist/node/server/resolveServerPassword.d.ts.map +1 -0
- package/dist/node/server/resolveServerPassword.js +25 -0
- package/dist/node/server/resolveServerPassword.js.map +1 -0
- package/dist/node/server/server.d.ts +22 -0
- package/dist/node/server/server.d.ts.map +1 -0
- package/dist/node/server/server.js +225 -0
- package/dist/node/server/server.js.map +1 -0
- package/dist/node/server/serverinit.d.ts +21 -0
- package/dist/node/server/serverinit.d.ts.map +1 -0
- package/dist/node/server/serverinit.js +317 -0
- package/dist/node/server/serverinit.js.map +1 -0
- package/dist/node/server/types.d.ts +167 -0
- package/dist/node/server/types.d.ts.map +1 -0
- package/dist/node/server/types.js +24 -0
- package/dist/node/server/types.js.map +1 -0
- package/dist/node/server/validation.d.ts +47 -0
- package/dist/node/server/validation.d.ts.map +1 -0
- package/dist/node/server/validation.js +114 -0
- package/dist/node/server/validation.js.map +1 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.d.ts +48 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.d.ts.map +1 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.js +113 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.js.map +1 -0
- package/dist/reactnative/index.d.ts +1 -0
- package/dist/reactnative/index.d.ts.map +1 -1
- package/dist/reactnative/index.js +4 -1
- package/dist/reactnative/index.js.map +1 -1
- package/package.json +15 -3
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TenantManager handles loading, caching, and registration of tenants.
|
|
4
|
+
*
|
|
5
|
+
* Uses a global server identity (one per server, not per tenant) for
|
|
6
|
+
* authenticating with remote servers and opening tenant directories.
|
|
7
|
+
*
|
|
8
|
+
* When a tenant has a $publicinfos key (sent during publishToServer), the
|
|
9
|
+
* manager creates a real BaseMindooTenant for directory reading. User
|
|
10
|
+
* authentication is then validated against the admin-signed directory DB
|
|
11
|
+
* rather than a static JSON config.
|
|
12
|
+
*
|
|
13
|
+
* When no $publicinfos key is available, a SimpleMindooDirectory backed
|
|
14
|
+
* by config.json users[] is used as a fallback (useful for tests).
|
|
15
|
+
*
|
|
16
|
+
* A CompositeMindooDirectory wraps whichever directory source is used and
|
|
17
|
+
* also checks the global trusted-servers list, enabling server-to-server
|
|
18
|
+
* auth without servers being in each tenant's user directory.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.TenantManager = void 0;
|
|
22
|
+
const fs_1 = require("fs");
|
|
23
|
+
const path_1 = require("path");
|
|
24
|
+
const NodeCryptoAdapter_1 = require("../crypto/NodeCryptoAdapter");
|
|
25
|
+
const AuthenticationService_1 = require("../../core/appendonlystores/network/AuthenticationService");
|
|
26
|
+
const ServerNetworkContentAddressedStore_1 = require("../../appendonlystores/network/ServerNetworkContentAddressedStore");
|
|
27
|
+
const BaseMindooTenantFactory_1 = require("../../core/BaseMindooTenantFactory");
|
|
28
|
+
const RSAEncryption_1 = require("../../core/crypto/RSAEncryption");
|
|
29
|
+
const privateKeyEncryption_1 = require("../../core/crypto/privateKeyEncryption");
|
|
30
|
+
const KeyBag_1 = require("../../core/keys/KeyBag");
|
|
31
|
+
const types_1 = require("../../core/types");
|
|
32
|
+
const StoreFactory_1 = require("./StoreFactory");
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// StoreFactoryAdapter
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
class StoreFactoryAdapter {
|
|
37
|
+
constructor(storeFactory) {
|
|
38
|
+
this.storeFactory = storeFactory;
|
|
39
|
+
}
|
|
40
|
+
createStore(dbId, _options) {
|
|
41
|
+
return { docStore: this.storeFactory.getStore(dbId) };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// SimpleMindooDirectory — config-based fallback
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
class SimpleMindooDirectory {
|
|
48
|
+
constructor(config) {
|
|
49
|
+
this.users = new Map();
|
|
50
|
+
this.revokedUsers = new Set();
|
|
51
|
+
this.adminSigningPublicKey = config.adminSigningPublicKey;
|
|
52
|
+
if (config.users) {
|
|
53
|
+
for (const user of config.users) {
|
|
54
|
+
this.users.set(user.username.toLowerCase(), user);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async getUserPublicKeys(username) {
|
|
59
|
+
const normalizedUsername = username.toLowerCase();
|
|
60
|
+
if (this.revokedUsers.has(normalizedUsername)) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const user = this.users.get(normalizedUsername);
|
|
64
|
+
if (!user) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
signingPublicKey: user.signingPublicKey,
|
|
69
|
+
encryptionPublicKey: user.encryptionPublicKey,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async isUserRevoked(username) {
|
|
73
|
+
return this.revokedUsers.has(username.toLowerCase());
|
|
74
|
+
}
|
|
75
|
+
async validatePublicSigningKey(publicKey) {
|
|
76
|
+
if (publicKey === this.adminSigningPublicKey) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
for (const [, user] of this.users) {
|
|
80
|
+
if (user.signingPublicKey === publicKey) {
|
|
81
|
+
if (!this.revokedUsers.has(user.username.toLowerCase())) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// CompositeMindooDirectory — wraps tenant directory + trusted servers
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
/**
|
|
93
|
+
* Wraps a per-tenant directory (real or config-based) and also checks
|
|
94
|
+
* the global trusted-servers list. Holds a reference to the array so
|
|
95
|
+
* runtime changes via the admin API are immediately visible.
|
|
96
|
+
*/
|
|
97
|
+
class CompositeMindooDirectory {
|
|
98
|
+
constructor(inner, trustedServers, adminBootstrapIdentity) {
|
|
99
|
+
this.inner = inner;
|
|
100
|
+
this.trustedServers = trustedServers;
|
|
101
|
+
this.adminBootstrapIdentity = adminBootstrapIdentity;
|
|
102
|
+
this.adminUsernameNormalized = adminBootstrapIdentity?.username.toLowerCase() ?? null;
|
|
103
|
+
}
|
|
104
|
+
async getUserPublicKeys(username) {
|
|
105
|
+
const normalizedUsername = username.toLowerCase();
|
|
106
|
+
// Bootstrap special-case: allow configured admin identity to authenticate
|
|
107
|
+
// even before directory grantaccess docs are present on the server.
|
|
108
|
+
if (this.adminBootstrapIdentity &&
|
|
109
|
+
this.adminUsernameNormalized &&
|
|
110
|
+
normalizedUsername === this.adminUsernameNormalized) {
|
|
111
|
+
return {
|
|
112
|
+
signingPublicKey: this.adminBootstrapIdentity.signingPublicKey,
|
|
113
|
+
encryptionPublicKey: this.adminBootstrapIdentity.encryptionPublicKey,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const result = await this.inner.getUserPublicKeys(username);
|
|
117
|
+
if (result)
|
|
118
|
+
return result;
|
|
119
|
+
for (const server of this.trustedServers) {
|
|
120
|
+
if (server.name.toLowerCase() === normalizedUsername) {
|
|
121
|
+
return {
|
|
122
|
+
signingPublicKey: server.signingPublicKey,
|
|
123
|
+
encryptionPublicKey: server.encryptionPublicKey,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
async isUserRevoked(username) {
|
|
130
|
+
const normalizedUsername = username.toLowerCase();
|
|
131
|
+
if (this.adminUsernameNormalized && normalizedUsername === this.adminUsernameNormalized) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
for (const server of this.trustedServers) {
|
|
135
|
+
if (server.name.toLowerCase() === normalizedUsername) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return this.inner.isUserRevoked(username);
|
|
140
|
+
}
|
|
141
|
+
async validatePublicSigningKey(publicKey) {
|
|
142
|
+
if (this.adminBootstrapIdentity && this.adminBootstrapIdentity.signingPublicKey === publicKey) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
const innerResult = await this.inner.validatePublicSigningKey(publicKey);
|
|
146
|
+
if (innerResult)
|
|
147
|
+
return true;
|
|
148
|
+
for (const server of this.trustedServers) {
|
|
149
|
+
if (server.signingPublicKey === publicKey) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// TenantManager
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
/**
|
|
160
|
+
* TenantManager is responsible for:
|
|
161
|
+
* - Loading the global server identity and trusted servers
|
|
162
|
+
* - Loading tenant configurations from disk
|
|
163
|
+
* - Caching loaded tenants
|
|
164
|
+
* - Registering new tenants
|
|
165
|
+
* - Managing tenant stores and authentication services
|
|
166
|
+
* - Creating a real MindooDB tenant for directory reading (when keys available)
|
|
167
|
+
* - Runtime management of trusted servers
|
|
168
|
+
*/
|
|
169
|
+
class TenantManager {
|
|
170
|
+
constructor(dataDir, serverPassword) {
|
|
171
|
+
this.loadedTenants = new Map();
|
|
172
|
+
this.serverIdentity = null;
|
|
173
|
+
this.trustedServers = [];
|
|
174
|
+
this.dataDir = dataDir;
|
|
175
|
+
this.serverPassword = serverPassword;
|
|
176
|
+
this.cryptoAdapter = new NodeCryptoAdapter_1.NodeCryptoAdapter();
|
|
177
|
+
if (!(0, fs_1.existsSync)(dataDir)) {
|
|
178
|
+
(0, fs_1.mkdirSync)(dataDir, { recursive: true });
|
|
179
|
+
console.log(`[TenantManager] Created data directory: ${dataDir}`);
|
|
180
|
+
}
|
|
181
|
+
// Load global server identity
|
|
182
|
+
const identityPath = (0, path_1.join)(dataDir, "server.identity.json");
|
|
183
|
+
if ((0, fs_1.existsSync)(identityPath)) {
|
|
184
|
+
this.serverIdentity = JSON.parse((0, fs_1.readFileSync)(identityPath, "utf-8"));
|
|
185
|
+
console.log(`[TenantManager] Loaded server identity: ${this.serverIdentity.username}`);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.log(`[TenantManager] No server.identity.json found (run "npm run init" to create one)`);
|
|
189
|
+
}
|
|
190
|
+
// Load trusted servers
|
|
191
|
+
const trustedPath = (0, path_1.join)(dataDir, "trusted-servers.json");
|
|
192
|
+
if ((0, fs_1.existsSync)(trustedPath)) {
|
|
193
|
+
this.trustedServers = JSON.parse((0, fs_1.readFileSync)(trustedPath, "utf-8"));
|
|
194
|
+
console.log(`[TenantManager] Loaded ${this.trustedServers.length} trusted server(s)`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// =======================================================================
|
|
198
|
+
// Server identity
|
|
199
|
+
// =======================================================================
|
|
200
|
+
getServerIdentity() {
|
|
201
|
+
return this.serverIdentity;
|
|
202
|
+
}
|
|
203
|
+
getServerPublicInfo() {
|
|
204
|
+
if (!this.serverIdentity)
|
|
205
|
+
return null;
|
|
206
|
+
return {
|
|
207
|
+
name: this.serverIdentity.username,
|
|
208
|
+
signingPublicKey: this.serverIdentity.userSigningKeyPair.publicKey,
|
|
209
|
+
encryptionPublicKey: this.serverIdentity.userEncryptionKeyPair.publicKey,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
// =======================================================================
|
|
213
|
+
// Trusted server management
|
|
214
|
+
// =======================================================================
|
|
215
|
+
listTrustedServers() {
|
|
216
|
+
return [...this.trustedServers];
|
|
217
|
+
}
|
|
218
|
+
addTrustedServer(server) {
|
|
219
|
+
const existing = this.trustedServers.find((s) => s.name.toLowerCase() === server.name.toLowerCase());
|
|
220
|
+
if (existing) {
|
|
221
|
+
throw new Error(`Trusted server "${server.name}" already exists`);
|
|
222
|
+
}
|
|
223
|
+
this.trustedServers.push(server);
|
|
224
|
+
this.persistTrustedServers();
|
|
225
|
+
console.log(`[TenantManager] Added trusted server: ${server.name}`);
|
|
226
|
+
}
|
|
227
|
+
removeTrustedServer(name) {
|
|
228
|
+
const idx = this.trustedServers.findIndex((s) => s.name.toLowerCase() === name.toLowerCase());
|
|
229
|
+
if (idx === -1)
|
|
230
|
+
return false;
|
|
231
|
+
this.trustedServers.splice(idx, 1);
|
|
232
|
+
this.persistTrustedServers();
|
|
233
|
+
console.log(`[TenantManager] Removed trusted server: ${name}`);
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
persistTrustedServers() {
|
|
237
|
+
const filePath = (0, path_1.join)(this.dataDir, "trusted-servers.json");
|
|
238
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(this.trustedServers, null, 2), "utf-8");
|
|
239
|
+
}
|
|
240
|
+
getServerKeyBagPath() {
|
|
241
|
+
return (0, path_1.join)(this.dataDir, "server.keybag");
|
|
242
|
+
}
|
|
243
|
+
async loadServerKeyBag() {
|
|
244
|
+
if (!this.serverIdentity || !this.serverPassword) {
|
|
245
|
+
throw new Error("Server identity and server password are required to manage tenant $publicinfos keys");
|
|
246
|
+
}
|
|
247
|
+
const keyBag = new KeyBag_1.KeyBag(this.serverIdentity.userEncryptionKeyPair.privateKey, this.serverPassword, this.cryptoAdapter);
|
|
248
|
+
const keyBagPath = this.getServerKeyBagPath();
|
|
249
|
+
if ((0, fs_1.existsSync)(keyBagPath)) {
|
|
250
|
+
const data = (0, fs_1.readFileSync)(keyBagPath);
|
|
251
|
+
await keyBag.load(new Uint8Array(data));
|
|
252
|
+
}
|
|
253
|
+
return keyBag;
|
|
254
|
+
}
|
|
255
|
+
async saveServerKeyBag(keyBag) {
|
|
256
|
+
(0, fs_1.writeFileSync)(this.getServerKeyBagPath(), Buffer.from(await keyBag.save()));
|
|
257
|
+
}
|
|
258
|
+
bytesToBase64(bytes) {
|
|
259
|
+
return Buffer.from(bytes).toString("base64");
|
|
260
|
+
}
|
|
261
|
+
mergeUniqueKeys(keys) {
|
|
262
|
+
const seen = new Set();
|
|
263
|
+
const unique = [];
|
|
264
|
+
for (const key of keys) {
|
|
265
|
+
const signature = this.bytesToBase64(key);
|
|
266
|
+
if (seen.has(signature)) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
seen.add(signature);
|
|
270
|
+
unique.push(key);
|
|
271
|
+
}
|
|
272
|
+
return unique;
|
|
273
|
+
}
|
|
274
|
+
async computePublicInfosFingerprint(key) {
|
|
275
|
+
const digest = await this.cryptoAdapter.getSubtle().digest("SHA-256", key);
|
|
276
|
+
return Array.from(new Uint8Array(digest).slice(0, 8))
|
|
277
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
278
|
+
.join(":");
|
|
279
|
+
}
|
|
280
|
+
async decryptEncryptedPublicInfosKey(base64Payload) {
|
|
281
|
+
if (!this.serverIdentity) {
|
|
282
|
+
throw new Error("Server identity not initialized; cannot decrypt encrypted $publicinfos payload");
|
|
283
|
+
}
|
|
284
|
+
if (!this.serverPassword) {
|
|
285
|
+
throw new Error("Server password not configured; cannot decrypt encrypted $publicinfos payload");
|
|
286
|
+
}
|
|
287
|
+
const privateKeyBuffer = await (0, privateKeyEncryption_1.decryptPrivateKey)(this.cryptoAdapter, this.serverIdentity.userEncryptionKeyPair.privateKey, this.serverPassword, "encryption");
|
|
288
|
+
const privateKey = await this.cryptoAdapter.getSubtle().importKey("pkcs8", privateKeyBuffer, {
|
|
289
|
+
name: "RSA-OAEP",
|
|
290
|
+
hash: "SHA-256",
|
|
291
|
+
}, false, ["decrypt"]);
|
|
292
|
+
const decrypted = await new RSAEncryption_1.RSAEncryption(this.cryptoAdapter).decrypt(new Uint8Array(Buffer.from(base64Payload, "base64")), privateKey);
|
|
293
|
+
return new Uint8Array(decrypted);
|
|
294
|
+
}
|
|
295
|
+
async resolveIncomingPublicInfosKey(request) {
|
|
296
|
+
if (request.encryptedPublicInfosKey) {
|
|
297
|
+
return this.decryptEncryptedPublicInfosKey(request.encryptedPublicInfosKey);
|
|
298
|
+
}
|
|
299
|
+
if (request.publicInfosKey) {
|
|
300
|
+
return new Uint8Array(Buffer.from(request.publicInfosKey, "base64"));
|
|
301
|
+
}
|
|
302
|
+
throw new Error("Tenant registration requires encryptedPublicInfosKey or publicInfosKey");
|
|
303
|
+
}
|
|
304
|
+
async getStoredPublicInfosKeys(tenantId) {
|
|
305
|
+
const keys = [];
|
|
306
|
+
if (this.serverIdentity && this.serverPassword && (0, fs_1.existsSync)(this.getServerKeyBagPath())) {
|
|
307
|
+
const keyBag = await this.loadServerKeyBag();
|
|
308
|
+
keys.push(...await keyBag.getAllKeys("doc", tenantId, types_1.PUBLIC_INFOS_KEY_ID));
|
|
309
|
+
}
|
|
310
|
+
return this.mergeUniqueKeys(keys);
|
|
311
|
+
}
|
|
312
|
+
async persistTenantPublicInfosKey(tenantId, key) {
|
|
313
|
+
const keyBag = await this.loadServerKeyBag();
|
|
314
|
+
const existingKeys = await keyBag.getAllKeys("doc", tenantId, types_1.PUBLIC_INFOS_KEY_ID);
|
|
315
|
+
const incomingSignature = this.bytesToBase64(key);
|
|
316
|
+
const alreadyStored = existingKeys.some((entry) => this.bytesToBase64(entry) === incomingSignature);
|
|
317
|
+
if (!alreadyStored) {
|
|
318
|
+
await keyBag.set("doc", tenantId, types_1.PUBLIC_INFOS_KEY_ID, key, Date.now());
|
|
319
|
+
await this.saveServerKeyBag(keyBag);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
async listTenantPublicInfosFingerprints(tenantId) {
|
|
323
|
+
const normalizedId = tenantId.toLowerCase();
|
|
324
|
+
const configPath = (0, path_1.join)(this.dataDir, normalizedId, "config.json");
|
|
325
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
326
|
+
throw new Error(`Tenant ${normalizedId} not found`);
|
|
327
|
+
}
|
|
328
|
+
const fingerprints = await Promise.all((await this.getStoredPublicInfosKeys(normalizedId)).map((key) => this.computePublicInfosFingerprint(key)));
|
|
329
|
+
return [...new Set(fingerprints)].sort();
|
|
330
|
+
}
|
|
331
|
+
// =======================================================================
|
|
332
|
+
// Tenant management
|
|
333
|
+
// =======================================================================
|
|
334
|
+
async registerTenant(request) {
|
|
335
|
+
const tenantId = request.tenantId.toLowerCase();
|
|
336
|
+
const tenantDir = (0, path_1.join)(this.dataDir, tenantId);
|
|
337
|
+
const configPath = (0, path_1.join)(tenantDir, "config.json");
|
|
338
|
+
if (!this.serverIdentity || !this.serverPassword) {
|
|
339
|
+
throw new Error("Tenant registration requires an unlocked server identity to store $publicinfos keys");
|
|
340
|
+
}
|
|
341
|
+
const publicInfosKey = await this.resolveIncomingPublicInfosKey(request);
|
|
342
|
+
if ((0, fs_1.existsSync)(configPath)) {
|
|
343
|
+
const existingConfig = JSON.parse((0, fs_1.readFileSync)(configPath, "utf-8"));
|
|
344
|
+
const incomingSignature = this.bytesToBase64(publicInfosKey);
|
|
345
|
+
const existingKeys = await this.getStoredPublicInfosKeys(tenantId);
|
|
346
|
+
const hasMatch = existingKeys.some((key) => this.bytesToBase64(key) === incomingSignature);
|
|
347
|
+
if (hasMatch) {
|
|
348
|
+
console.log(`[TenantManager] Tenant ${tenantId} already registered with matching $publicinfos key`);
|
|
349
|
+
return {
|
|
350
|
+
context: { tenantId, config: existingConfig },
|
|
351
|
+
created: false,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
throw new Error(`Tenant ${tenantId} already exists with different $publicinfos key`);
|
|
355
|
+
}
|
|
356
|
+
(0, fs_1.mkdirSync)(tenantDir, { recursive: true });
|
|
357
|
+
const config = {
|
|
358
|
+
adminUsername: request.adminUsername,
|
|
359
|
+
adminSigningPublicKey: request.adminSigningPublicKey,
|
|
360
|
+
adminEncryptionPublicKey: request.adminEncryptionPublicKey,
|
|
361
|
+
defaultStoreType: request.defaultStoreType || "file",
|
|
362
|
+
users: [],
|
|
363
|
+
};
|
|
364
|
+
try {
|
|
365
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
366
|
+
await this.persistTenantPublicInfosKey(tenantId, publicInfosKey);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
(0, fs_1.rmSync)(tenantDir, { recursive: true, force: true });
|
|
370
|
+
throw error;
|
|
371
|
+
}
|
|
372
|
+
console.log(`[TenantManager] Registered tenant: ${tenantId} ($publicinfos stored in server keybag)`);
|
|
373
|
+
return {
|
|
374
|
+
context: { tenantId, config },
|
|
375
|
+
created: true,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
async getTenant(tenantId) {
|
|
379
|
+
const normalizedId = tenantId.toLowerCase();
|
|
380
|
+
const cached = this.loadedTenants.get(normalizedId);
|
|
381
|
+
if (cached) {
|
|
382
|
+
return cached;
|
|
383
|
+
}
|
|
384
|
+
const loaded = await this.loadTenant(normalizedId);
|
|
385
|
+
this.loadedTenants.set(normalizedId, loaded);
|
|
386
|
+
return loaded;
|
|
387
|
+
}
|
|
388
|
+
tenantExists(tenantId) {
|
|
389
|
+
const normalizedId = tenantId.toLowerCase();
|
|
390
|
+
const tenantDir = (0, path_1.join)(this.dataDir, normalizedId);
|
|
391
|
+
const configPath = (0, path_1.join)(tenantDir, "config.json");
|
|
392
|
+
return (0, fs_1.existsSync)(configPath);
|
|
393
|
+
}
|
|
394
|
+
listTenants() {
|
|
395
|
+
if (!(0, fs_1.existsSync)(this.dataDir)) {
|
|
396
|
+
return [];
|
|
397
|
+
}
|
|
398
|
+
const entries = (0, fs_1.readdirSync)(this.dataDir);
|
|
399
|
+
const tenants = [];
|
|
400
|
+
for (const entry of entries) {
|
|
401
|
+
const entryPath = (0, path_1.join)(this.dataDir, entry);
|
|
402
|
+
const configPath = (0, path_1.join)(entryPath, "config.json");
|
|
403
|
+
if ((0, fs_1.statSync)(entryPath).isDirectory() && (0, fs_1.existsSync)(configPath)) {
|
|
404
|
+
tenants.push(entry);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return tenants.sort();
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Update operator-owned fields of an existing tenant configuration.
|
|
411
|
+
* Only the fields present in `updates` are overwritten.
|
|
412
|
+
*/
|
|
413
|
+
updateTenantConfig(tenantId, updates) {
|
|
414
|
+
const normalizedId = tenantId.toLowerCase();
|
|
415
|
+
const configPath = (0, path_1.join)(this.dataDir, normalizedId, "config.json");
|
|
416
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
417
|
+
throw new Error(`Tenant ${normalizedId} not found`);
|
|
418
|
+
}
|
|
419
|
+
const config = JSON.parse((0, fs_1.readFileSync)(configPath, "utf-8"));
|
|
420
|
+
if (updates.defaultStoreType !== undefined) {
|
|
421
|
+
config.defaultStoreType = updates.defaultStoreType;
|
|
422
|
+
}
|
|
423
|
+
if (updates.remoteServers !== undefined) {
|
|
424
|
+
config.remoteServers = updates.remoteServers;
|
|
425
|
+
}
|
|
426
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
427
|
+
this.loadedTenants.delete(normalizedId);
|
|
428
|
+
console.log(`[TenantManager] Updated tenant config: ${normalizedId}`);
|
|
429
|
+
}
|
|
430
|
+
async removeTenant(tenantId) {
|
|
431
|
+
const normalizedId = tenantId.toLowerCase();
|
|
432
|
+
const tenantDir = (0, path_1.join)(this.dataDir, normalizedId);
|
|
433
|
+
if (!(0, fs_1.existsSync)(tenantDir)) {
|
|
434
|
+
throw new Error(`Tenant ${normalizedId} does not exist`);
|
|
435
|
+
}
|
|
436
|
+
this.loadedTenants.delete(normalizedId);
|
|
437
|
+
if (this.serverIdentity && this.serverPassword && (0, fs_1.existsSync)(this.getServerKeyBagPath())) {
|
|
438
|
+
const keyBag = await this.loadServerKeyBag();
|
|
439
|
+
await keyBag.deleteKey("doc", normalizedId, types_1.PUBLIC_INFOS_KEY_ID);
|
|
440
|
+
await this.saveServerKeyBag(keyBag);
|
|
441
|
+
}
|
|
442
|
+
(0, fs_1.rmSync)(tenantDir, { recursive: true, force: true });
|
|
443
|
+
console.log(`[TenantManager] Removed tenant: ${normalizedId}`);
|
|
444
|
+
}
|
|
445
|
+
// =======================================================================
|
|
446
|
+
// Per-tenant sync server management
|
|
447
|
+
// =======================================================================
|
|
448
|
+
getTenantSyncServers(tenantId) {
|
|
449
|
+
const normalizedId = tenantId.toLowerCase();
|
|
450
|
+
const configPath = (0, path_1.join)(this.dataDir, normalizedId, "config.json");
|
|
451
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
452
|
+
throw new Error(`Tenant ${normalizedId} not found`);
|
|
453
|
+
}
|
|
454
|
+
const config = JSON.parse((0, fs_1.readFileSync)(configPath, "utf-8"));
|
|
455
|
+
return (config.remoteServers || []);
|
|
456
|
+
}
|
|
457
|
+
addTenantSyncServer(tenantId, server) {
|
|
458
|
+
const normalizedId = tenantId.toLowerCase();
|
|
459
|
+
const configPath = (0, path_1.join)(this.dataDir, normalizedId, "config.json");
|
|
460
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
461
|
+
throw new Error(`Tenant ${normalizedId} not found`);
|
|
462
|
+
}
|
|
463
|
+
const config = JSON.parse((0, fs_1.readFileSync)(configPath, "utf-8"));
|
|
464
|
+
const servers = (config.remoteServers || []);
|
|
465
|
+
const idx = servers.findIndex((s) => s.name?.toLowerCase() === server.name.toLowerCase());
|
|
466
|
+
if (idx >= 0) {
|
|
467
|
+
servers[idx] = server;
|
|
468
|
+
console.log(`[TenantManager] Updated sync server "${server.name}" for tenant ${normalizedId}`);
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
servers.push(server);
|
|
472
|
+
console.log(`[TenantManager] Added sync server "${server.name}" for tenant ${normalizedId}`);
|
|
473
|
+
}
|
|
474
|
+
config.remoteServers = servers;
|
|
475
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
476
|
+
this.loadedTenants.delete(normalizedId);
|
|
477
|
+
}
|
|
478
|
+
removeTenantSyncServer(tenantId, serverName) {
|
|
479
|
+
const normalizedId = tenantId.toLowerCase();
|
|
480
|
+
const configPath = (0, path_1.join)(this.dataDir, normalizedId, "config.json");
|
|
481
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
482
|
+
throw new Error(`Tenant ${normalizedId} not found`);
|
|
483
|
+
}
|
|
484
|
+
const config = JSON.parse((0, fs_1.readFileSync)(configPath, "utf-8"));
|
|
485
|
+
const servers = (config.remoteServers || []);
|
|
486
|
+
const idx = servers.findIndex((s) => s.name?.toLowerCase() === serverName.toLowerCase());
|
|
487
|
+
if (idx === -1)
|
|
488
|
+
return false;
|
|
489
|
+
servers.splice(idx, 1);
|
|
490
|
+
config.remoteServers = servers;
|
|
491
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
492
|
+
this.loadedTenants.delete(normalizedId);
|
|
493
|
+
console.log(`[TenantManager] Removed sync server "${serverName}" from tenant ${normalizedId}`);
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
// =======================================================================
|
|
497
|
+
// Server stores
|
|
498
|
+
// =======================================================================
|
|
499
|
+
async getServerStore(tenantId, dbId) {
|
|
500
|
+
const tenant = await this.getTenant(tenantId);
|
|
501
|
+
const cached = tenant.serverStores.get(dbId);
|
|
502
|
+
if (cached) {
|
|
503
|
+
return cached;
|
|
504
|
+
}
|
|
505
|
+
const localStore = tenant.storeFactory.getStore(dbId);
|
|
506
|
+
const serverStore = new ServerNetworkContentAddressedStore_1.ServerNetworkContentAddressedStore(localStore, tenant.directory, tenant.authService, this.cryptoAdapter);
|
|
507
|
+
tenant.serverStores.set(dbId, serverStore);
|
|
508
|
+
console.log(`[TenantManager] Created server store for ${tenantId}/${dbId}`);
|
|
509
|
+
return serverStore;
|
|
510
|
+
}
|
|
511
|
+
async getStore(tenantId, dbId) {
|
|
512
|
+
const tenant = await this.getTenant(tenantId);
|
|
513
|
+
return tenant.storeFactory.getStore(dbId);
|
|
514
|
+
}
|
|
515
|
+
async getAuthService(tenantId) {
|
|
516
|
+
const tenant = await this.getTenant(tenantId);
|
|
517
|
+
return tenant.authService;
|
|
518
|
+
}
|
|
519
|
+
getCryptoAdapter() {
|
|
520
|
+
return this.cryptoAdapter;
|
|
521
|
+
}
|
|
522
|
+
async reloadTenant(tenantId) {
|
|
523
|
+
const normalizedId = tenantId.toLowerCase();
|
|
524
|
+
this.loadedTenants.delete(normalizedId);
|
|
525
|
+
return this.getTenant(normalizedId);
|
|
526
|
+
}
|
|
527
|
+
clearCache() {
|
|
528
|
+
this.loadedTenants.clear();
|
|
529
|
+
console.log(`[TenantManager] Cleared tenant cache`);
|
|
530
|
+
}
|
|
531
|
+
// -----------------------------------------------------------------------
|
|
532
|
+
// Private helpers
|
|
533
|
+
// -----------------------------------------------------------------------
|
|
534
|
+
async loadTenant(tenantId) {
|
|
535
|
+
const tenantDir = (0, path_1.join)(this.dataDir, tenantId);
|
|
536
|
+
const configPath = (0, path_1.join)(tenantDir, "config.json");
|
|
537
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
538
|
+
throw new Error(`Tenant ${tenantId} not found: ${configPath}`);
|
|
539
|
+
}
|
|
540
|
+
const configJson = (0, fs_1.readFileSync)(configPath, "utf-8");
|
|
541
|
+
const config = JSON.parse(configJson);
|
|
542
|
+
const context = { tenantId, config };
|
|
543
|
+
const storeFactory = new StoreFactory_1.StoreFactory(tenantId, config, this.dataDir);
|
|
544
|
+
// Build the inner directory (real or config-based fallback)
|
|
545
|
+
let innerDirectory;
|
|
546
|
+
let mindooTenant;
|
|
547
|
+
const publicInfosKeys = await this.getStoredPublicInfosKeys(tenantId);
|
|
548
|
+
if (publicInfosKeys.length > 0 && this.serverIdentity && this.serverPassword) {
|
|
549
|
+
try {
|
|
550
|
+
const result = await this.createDirectoryTenant(tenantId, config, storeFactory, publicInfosKeys);
|
|
551
|
+
mindooTenant = result.tenant;
|
|
552
|
+
innerDirectory = await mindooTenant.openDirectory();
|
|
553
|
+
console.log(`[TenantManager] Loaded tenant ${tenantId} with real directory`);
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
console.error(`[TenantManager] Failed to create real directory for ${tenantId}, falling back to config:`, error);
|
|
557
|
+
innerDirectory = new SimpleMindooDirectory(config);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
if (publicInfosKeys.length > 0 && !this.serverIdentity) {
|
|
562
|
+
console.log(`[TenantManager] Tenant ${tenantId} has $publicinfos keys but no server identity; using config-based directory`);
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
console.log(`[TenantManager] No $publicinfos keys for ${tenantId}, using config-based directory`);
|
|
566
|
+
}
|
|
567
|
+
innerDirectory = new SimpleMindooDirectory(config);
|
|
568
|
+
}
|
|
569
|
+
// Wrap with CompositeMindooDirectory so trusted servers are also recognized
|
|
570
|
+
const directory = new CompositeMindooDirectory(innerDirectory, this.trustedServers, config.adminUsername
|
|
571
|
+
? {
|
|
572
|
+
username: config.adminUsername,
|
|
573
|
+
signingPublicKey: config.adminSigningPublicKey,
|
|
574
|
+
encryptionPublicKey: config.adminEncryptionPublicKey,
|
|
575
|
+
}
|
|
576
|
+
: undefined);
|
|
577
|
+
const authService = new AuthenticationService_1.AuthenticationService(this.cryptoAdapter, directory, tenantId);
|
|
578
|
+
console.log(`[TenantManager] Loaded tenant: ${tenantId}`);
|
|
579
|
+
return {
|
|
580
|
+
context,
|
|
581
|
+
storeFactory,
|
|
582
|
+
authService,
|
|
583
|
+
directory,
|
|
584
|
+
mindooTenant,
|
|
585
|
+
serverStores: new Map(),
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Create a real BaseMindooTenant for directory reading using the global
|
|
590
|
+
* server identity.
|
|
591
|
+
*/
|
|
592
|
+
async createDirectoryTenant(tenantId, config, storeFactory, publicInfosKeys) {
|
|
593
|
+
const storeFactoryAdapter = new StoreFactoryAdapter(storeFactory);
|
|
594
|
+
const factory = new BaseMindooTenantFactory_1.BaseMindooTenantFactory(storeFactoryAdapter, this.cryptoAdapter);
|
|
595
|
+
const serverUser = this.serverIdentity;
|
|
596
|
+
// Create a KeyBag using the server user's encryption key
|
|
597
|
+
const keyBag = new KeyBag_1.KeyBag(serverUser.userEncryptionKeyPair.privateKey, this.serverPassword, this.cryptoAdapter);
|
|
598
|
+
for (const publicInfosKey of this.mergeUniqueKeys(publicInfosKeys)) {
|
|
599
|
+
await keyBag.set("doc", tenantId, types_1.PUBLIC_INFOS_KEY_ID, publicInfosKey);
|
|
600
|
+
}
|
|
601
|
+
// Collect trusted server signing keys for additionalTrustedKeys
|
|
602
|
+
const openOptions = {};
|
|
603
|
+
if (this.trustedServers.length > 0) {
|
|
604
|
+
const trustedKeys = new Map();
|
|
605
|
+
for (const server of this.trustedServers) {
|
|
606
|
+
trustedKeys.set(server.signingPublicKey, true);
|
|
607
|
+
}
|
|
608
|
+
openOptions.additionalTrustedKeys = trustedKeys;
|
|
609
|
+
}
|
|
610
|
+
const tenant = await factory.openTenant(tenantId, config.adminSigningPublicKey, config.adminEncryptionPublicKey, serverUser, this.serverPassword, keyBag, openOptions);
|
|
611
|
+
return { tenant };
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
exports.TenantManager = TenantManager;
|
|
615
|
+
//# sourceMappingURL=TenantManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TenantManager.js","sourceRoot":"","sources":["../../../src/node/server/TenantManager.ts"],"names":[],"mappings":"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"}
|