mindoodb 0.0.85 → 0.0.88
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 +6 -2
- package/README.md +6 -4
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +2 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +151 -12
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +340 -24
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
- package/dist/browser/index.mjs +14 -0
- package/dist/cloudflare/DurableObjectSql.d.ts +56 -0
- package/dist/cloudflare/DurableObjectSql.d.ts.map +1 -0
- package/dist/cloudflare/DurableObjectSql.js +180 -0
- package/dist/cloudflare/DurableObjectSql.js.map +1 -0
- package/dist/cloudflare/MindooDatabaseObject.d.ts +86 -0
- package/dist/cloudflare/MindooDatabaseObject.d.ts.map +1 -0
- package/dist/cloudflare/MindooDatabaseObject.js +614 -0
- package/dist/cloudflare/MindooDatabaseObject.js.map +1 -0
- package/dist/cloudflare/MindooServerObject.d.ts +63 -0
- package/dist/cloudflare/MindooServerObject.d.ts.map +1 -0
- package/dist/cloudflare/MindooServerObject.js +521 -0
- package/dist/cloudflare/MindooServerObject.js.map +1 -0
- package/dist/cloudflare/WorkersCryptoAdapter.d.ts +7 -0
- package/dist/cloudflare/WorkersCryptoAdapter.d.ts.map +1 -0
- package/dist/cloudflare/WorkersCryptoAdapter.js +14 -0
- package/dist/cloudflare/WorkersCryptoAdapter.js.map +1 -0
- package/dist/cloudflare/host.d.ts +49 -0
- package/dist/cloudflare/host.d.ts.map +1 -0
- package/dist/cloudflare/host.js +104 -0
- package/dist/cloudflare/host.js.map +1 -0
- package/dist/cloudflare/http.d.ts +91 -0
- package/dist/cloudflare/http.d.ts.map +1 -0
- package/dist/cloudflare/http.js +266 -0
- package/dist/cloudflare/http.js.map +1 -0
- package/dist/cloudflare/index.d.ts +12 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +20 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/cloudflare/storeRpc.d.ts +22 -0
- package/dist/cloudflare/storeRpc.d.ts.map +1 -0
- package/dist/cloudflare/storeRpc.js +85 -0
- package/dist/cloudflare/storeRpc.js.map +1 -0
- package/dist/cloudflare/types.d.ts +101 -0
- package/dist/cloudflare/types.d.ts.map +1 -0
- package/dist/cloudflare/types.js +10 -0
- package/dist/cloudflare/types.js.map +1 -0
- package/dist/cloudflare/worker.d.ts +25 -0
- package/dist/cloudflare/worker.d.ts.map +1 -0
- package/dist/cloudflare/worker.js +170 -0
- package/dist/cloudflare/worker.js.map +1 -0
- package/dist/core/BaseMindooDB.d.ts +95 -10
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +441 -98
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +43 -0
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +157 -6
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts +103 -0
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +371 -8
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantFactory.js +2 -1
- package/dist/core/BaseMindooTenantFactory.js.map +1 -1
- package/dist/core/ChangeDocDraft.d.ts +133 -0
- package/dist/core/ChangeDocDraft.d.ts.map +1 -0
- package/dist/core/ChangeDocDraft.js +492 -0
- package/dist/core/ChangeDocDraft.js.map +1 -0
- package/dist/core/MindooDBServerAdmin.d.ts.map +1 -1
- package/dist/core/MindooDBServerAdmin.js +2 -1
- package/dist/core/MindooDBServerAdmin.js.map +1 -1
- package/dist/core/accesscontrol/directoryProjection.d.ts.map +1 -1
- package/dist/core/accesscontrol/directoryProjection.js +19 -0
- package/dist/core/accesscontrol/directoryProjection.js.map +1 -1
- package/dist/core/accesscontrol/evaluate.d.ts +14 -0
- package/dist/core/accesscontrol/evaluate.d.ts.map +1 -1
- package/dist/core/accesscontrol/evaluate.js +42 -1
- package/dist/core/accesscontrol/evaluate.js.map +1 -1
- package/dist/core/accesscontrol/types.d.ts +88 -4
- package/dist/core/accesscontrol/types.d.ts.map +1 -1
- package/dist/core/accesscontrol/types.js +114 -1
- package/dist/core/accesscontrol/types.js.map +1 -1
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts +14 -0
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/AuthenticationService.js +27 -7
- package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -1
- package/dist/core/appendonlystores/network/IrohNetworkTransport.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/IrohNetworkTransport.js +12 -0
- package/dist/core/appendonlystores/network/IrohNetworkTransport.js.map +1 -1
- package/dist/core/appendonlystores/network/IrohStreamIO.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/IrohStreamIO.js +3 -23
- package/dist/core/appendonlystores/network/IrohStreamIO.js.map +1 -1
- package/dist/core/appendonlystores/rpc/RpcContentAddressedStore.d.ts +6 -0
- package/dist/core/appendonlystores/rpc/RpcContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/rpc/RpcContentAddressedStore.js +20 -1
- package/dist/core/appendonlystores/rpc/RpcContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/rpc/storeRpcCodec.d.ts.map +1 -1
- package/dist/core/appendonlystores/rpc/storeRpcCodec.js +3 -23
- package/dist/core/appendonlystores/rpc/storeRpcCodec.js.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.d.ts +7 -0
- package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.js +39 -30
- package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteDriver.d.ts +37 -1
- package/dist/core/appendonlystores/sqlite/SqliteDriver.d.ts.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteDriver.js +99 -40
- package/dist/core/appendonlystores/sqlite/SqliteDriver.js.map +1 -1
- package/dist/core/appendonlystores/syncStores.d.ts.map +1 -1
- package/dist/core/appendonlystores/syncStores.js +25 -5
- package/dist/core/appendonlystores/syncStores.js.map +1 -1
- package/dist/core/appendonlystores/types.d.ts +7 -1
- package/dist/core/appendonlystores/types.d.ts.map +1 -1
- package/dist/core/appendonlystores/types.js +1 -0
- package/dist/core/appendonlystores/types.js.map +1 -1
- package/dist/core/builtinDbInvariants.d.ts +49 -0
- package/dist/core/builtinDbInvariants.d.ts.map +1 -1
- package/dist/core/builtinDbInvariants.js +86 -1
- package/dist/core/builtinDbInvariants.js.map +1 -1
- package/dist/core/crypto/AuthChallenge.d.ts +68 -0
- package/dist/core/crypto/AuthChallenge.d.ts.map +1 -0
- package/dist/core/crypto/AuthChallenge.js +118 -0
- package/dist/core/crypto/AuthChallenge.js.map +1 -0
- package/dist/core/crypto/DomainStatement.d.ts +5 -3
- package/dist/core/crypto/DomainStatement.d.ts.map +1 -1
- package/dist/core/crypto/DomainStatement.js +5 -3
- package/dist/core/crypto/DomainStatement.js.map +1 -1
- package/dist/core/crypto/encryptedFields.d.ts +11 -0
- package/dist/core/crypto/encryptedFields.d.ts.map +1 -1
- package/dist/core/crypto/encryptedFields.js +18 -0
- package/dist/core/crypto/encryptedFields.js.map +1 -1
- package/dist/core/expressions/evaluateExpression.d.ts +8 -0
- package/dist/core/expressions/evaluateExpression.d.ts.map +1 -1
- package/dist/core/expressions/evaluateExpression.js +29 -4
- package/dist/core/expressions/evaluateExpression.js.map +1 -1
- package/dist/core/expressions/metadata.js +4 -4
- package/dist/core/expressions/metadata.js.map +1 -1
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +17 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/query/executeQuery.d.ts.map +1 -1
- package/dist/core/query/executeQuery.js +5 -1
- package/dist/core/query/executeQuery.js.map +1 -1
- package/dist/core/query/executeQueryInclude.d.ts.map +1 -1
- package/dist/core/query/executeQueryInclude.js +2 -0
- package/dist/core/query/executeQueryInclude.js.map +1 -1
- package/dist/core/query/queryView.d.ts.map +1 -1
- package/dist/core/query/queryView.js +5 -1
- package/dist/core/query/queryView.js.map +1 -1
- package/dist/core/types.d.ts +204 -10
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/uri/MindooURI.d.ts.map +1 -1
- package/dist/core/uri/MindooURI.js +3 -24
- package/dist/core/uri/MindooURI.js.map +1 -1
- package/dist/core/userkeys/index.d.ts +1 -0
- package/dist/core/userkeys/index.d.ts.map +1 -1
- package/dist/core/userkeys/index.js +5 -1
- package/dist/core/userkeys/index.js.map +1 -1
- package/dist/core/userkeys/sealedValues.d.ts +54 -0
- package/dist/core/userkeys/sealedValues.d.ts.map +1 -0
- package/dist/core/userkeys/sealedValues.js +67 -0
- package/dist/core/userkeys/sealedValues.js.map +1 -0
- package/dist/core/utils/base64.d.ts +17 -0
- package/dist/core/utils/base64.d.ts.map +1 -0
- package/dist/core/utils/base64.js +54 -0
- package/dist/core/utils/base64.js.map +1 -0
- package/dist/core/utils/dynamicImportInterop.d.ts +10 -0
- package/dist/core/utils/dynamicImportInterop.d.ts.map +1 -0
- package/dist/core/utils/dynamicImportInterop.js +22 -0
- package/dist/core/utils/dynamicImportInterop.js.map +1 -0
- package/dist/core/utils/idGeneration.d.ts.map +1 -1
- package/dist/core/utils/idGeneration.js +14 -3
- package/dist/core/utils/idGeneration.js.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +7 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -1
- package/dist/node/server/FsServerDataStore.d.ts +23 -0
- package/dist/node/server/FsServerDataStore.d.ts.map +1 -0
- package/dist/node/server/FsServerDataStore.js +59 -0
- package/dist/node/server/FsServerDataStore.js.map +1 -0
- package/dist/node/server/IrohServerEndpoint.d.ts +1 -1
- package/dist/node/server/IrohServerEndpoint.d.ts.map +1 -1
- package/dist/node/server/IrohServerRpc.d.ts +5 -5
- package/dist/node/server/IrohServerRpc.d.ts.map +1 -1
- package/dist/node/server/IrohServerRpc.js +1 -1
- package/dist/node/server/IrohServerRpc.js.map +1 -1
- package/dist/node/server/MindooDBServer.d.ts +29 -150
- package/dist/node/server/MindooDBServer.d.ts.map +1 -1
- package/dist/node/server/MindooDBServer.js +160 -1573
- package/dist/node/server/MindooDBServer.js.map +1 -1
- package/dist/node/server/PurgedDocRegistry.d.ts +4 -27
- package/dist/node/server/PurgedDocRegistry.d.ts.map +1 -1
- package/dist/node/server/PurgedDocRegistry.js +6 -83
- package/dist/node/server/PurgedDocRegistry.js.map +1 -1
- package/dist/node/server/StoreFactory.d.ts +1 -1
- package/dist/node/server/StoreFactory.d.ts.map +1 -1
- package/dist/node/server/TenantManager.d.ts +16 -284
- package/dist/node/server/TenantManager.d.ts.map +1 -1
- package/dist/node/server/TenantManager.js +35 -1168
- package/dist/node/server/TenantManager.js.map +1 -1
- package/dist/node/server/add-to-network.js +1 -1
- package/dist/node/server/add-to-network.js.map +1 -1
- package/dist/node/server/config.d.ts +11 -15
- package/dist/node/server/config.d.ts.map +1 -1
- package/dist/node/server/config.js +30 -245
- package/dist/node/server/config.js.map +1 -1
- package/dist/node/server/expressAdapter.d.ts +23 -0
- package/dist/node/server/expressAdapter.d.ts.map +1 -0
- package/dist/node/server/expressAdapter.js +108 -0
- package/dist/node/server/expressAdapter.js.map +1 -0
- package/dist/node/server/nativeIrohStreamIO.d.ts +1 -1
- package/dist/node/server/nativeIrohStreamIO.d.ts.map +1 -1
- package/dist/node/server/peer/FileClusterAuditStorage.d.ts +16 -0
- package/dist/node/server/peer/FileClusterAuditStorage.d.ts.map +1 -0
- package/dist/node/server/peer/FileClusterAuditStorage.js +39 -0
- package/dist/node/server/peer/FileClusterAuditStorage.js.map +1 -0
- package/dist/node/server/peer/IrohPeerLink.d.ts +1 -1
- package/dist/node/server/peer/IrohPeerLink.d.ts.map +1 -1
- package/dist/node/server/peer/routes.d.ts +10 -44
- package/dist/node/server/peer/routes.d.ts.map +1 -1
- package/dist/node/server/peer/routes.js +33 -275
- package/dist/node/server/peer/routes.js.map +1 -1
- package/dist/node/server/resolveServerPassword.js +1 -1
- package/dist/node/server/resolveServerPassword.js.map +1 -1
- package/dist/node/server/server.js +1 -1
- package/dist/node/server/server.js.map +1 -1
- package/dist/node/server/serverinit.js +1 -1
- package/dist/node/server/serverinit.js.map +1 -1
- package/dist/server/CapabilityMatcher.d.ts +60 -0
- package/dist/server/CapabilityMatcher.d.ts.map +1 -0
- package/dist/server/CapabilityMatcher.js +138 -0
- package/dist/server/CapabilityMatcher.js.map +1 -0
- package/dist/server/DeviceDiscoveryService.d.ts +36 -0
- package/dist/server/DeviceDiscoveryService.d.ts.map +1 -0
- package/dist/server/DeviceDiscoveryService.js +164 -0
- package/dist/server/DeviceDiscoveryService.js.map +1 -0
- package/dist/server/PurgedDocRegistry.d.ts +35 -0
- package/dist/server/PurgedDocRegistry.d.ts.map +1 -0
- package/dist/server/PurgedDocRegistry.js +90 -0
- package/dist/server/PurgedDocRegistry.js.map +1 -0
- package/dist/server/ServerDataStore.d.ts +67 -0
- package/dist/server/ServerDataStore.d.ts.map +1 -0
- package/dist/server/ServerDataStore.js +88 -0
- package/dist/server/ServerDataStore.js.map +1 -0
- package/dist/server/SyncEventBus.d.ts +39 -0
- package/dist/server/SyncEventBus.d.ts.map +1 -0
- package/dist/server/SyncEventBus.js +41 -0
- package/dist/server/SyncEventBus.js.map +1 -0
- package/dist/server/SystemAdminAuth.d.ts +82 -0
- package/dist/server/SystemAdminAuth.d.ts.map +1 -0
- package/dist/server/SystemAdminAuth.js +227 -0
- package/dist/server/SystemAdminAuth.js.map +1 -0
- package/dist/server/TenantManager.d.ts +366 -0
- package/dist/server/TenantManager.d.ts.map +1 -0
- package/dist/server/TenantManager.js +1416 -0
- package/dist/server/TenantManager.js.map +1 -0
- package/dist/server/http/MindooDBServerCore.d.ts +313 -0
- package/dist/server/http/MindooDBServerCore.d.ts.map +1 -0
- package/dist/server/http/MindooDBServerCore.js +1410 -0
- package/dist/server/http/MindooDBServerCore.js.map +1 -0
- package/dist/server/http/types.d.ts +89 -0
- package/dist/server/http/types.d.ts.map +1 -0
- package/dist/server/http/types.js +29 -0
- package/dist/server/http/types.js.map +1 -0
- package/dist/server/index.d.ts +32 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +76 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/peer/ClusterAuditLog.d.ts +71 -0
- package/dist/server/peer/ClusterAuditLog.d.ts.map +1 -0
- package/dist/server/peer/ClusterAuditLog.js +81 -0
- package/dist/server/peer/ClusterAuditLog.js.map +1 -0
- package/dist/server/peer/ClusterJobRunner.d.ts +43 -0
- package/dist/server/peer/ClusterJobRunner.d.ts.map +1 -0
- package/dist/server/peer/ClusterJobRunner.js +119 -0
- package/dist/server/peer/ClusterJobRunner.js.map +1 -0
- package/dist/server/peer/ClusterManager.d.ts +149 -0
- package/dist/server/peer/ClusterManager.d.ts.map +1 -0
- package/dist/server/peer/ClusterManager.js +292 -0
- package/dist/server/peer/ClusterManager.js.map +1 -0
- package/dist/server/peer/PeerAuthService.d.ts +69 -0
- package/dist/server/peer/PeerAuthService.d.ts.map +1 -0
- package/dist/server/peer/PeerAuthService.js +207 -0
- package/dist/server/peer/PeerAuthService.js.map +1 -0
- package/dist/server/peer/PeerReplicator.d.ts +303 -0
- package/dist/server/peer/PeerReplicator.d.ts.map +1 -0
- package/dist/server/peer/PeerReplicator.js +1072 -0
- package/dist/server/peer/PeerReplicator.js.map +1 -0
- package/dist/server/peer/clusterHttp.d.ts +113 -0
- package/dist/server/peer/clusterHttp.d.ts.map +1 -0
- package/dist/server/peer/clusterHttp.js +290 -0
- package/dist/server/peer/clusterHttp.js.map +1 -0
- package/dist/server/peer/types.d.ts +244 -0
- package/dist/server/peer/types.d.ts.map +1 -0
- package/dist/server/peer/types.js +189 -0
- package/dist/server/peer/types.js.map +1 -0
- package/dist/server/rateLimits.d.ts +119 -0
- package/dist/server/rateLimits.d.ts.map +1 -0
- package/dist/server/rateLimits.js +159 -0
- package/dist/server/rateLimits.js.map +1 -0
- package/dist/server/serverConfig.d.ts +37 -0
- package/dist/server/serverConfig.d.ts.map +1 -0
- package/dist/server/serverConfig.js +251 -0
- package/dist/server/serverConfig.js.map +1 -0
- package/dist/server/timestampProxy.d.ts +129 -0
- package/dist/server/timestampProxy.d.ts.map +1 -0
- package/dist/server/timestampProxy.js +361 -0
- package/dist/server/timestampProxy.js.map +1 -0
- package/dist/server/types.d.ts +267 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +56 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/validation.d.ts +43 -0
- package/dist/server/validation.d.ts.map +1 -0
- package/dist/server/validation.js +104 -0
- package/dist/server/validation.js.map +1 -0
- package/package.json +9 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Glue between Express and the platform-neutral handlers in
|
|
4
|
+
* {@link MindooDBServerCore}: turns an Express request into a
|
|
5
|
+
* {@link ServerRequest} and writes a {@link ServerResponse} back.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.toServerRequest = toServerRequest;
|
|
9
|
+
exports.sendServerResponse = sendServerResponse;
|
|
10
|
+
exports.route = route;
|
|
11
|
+
exports.guard = guard;
|
|
12
|
+
const types_1 = require("../../server/http/types");
|
|
13
|
+
const compressionMiddleware_1 = require("./compressionMiddleware");
|
|
14
|
+
/** Snapshot of an Express request, including what earlier guards resolved. */
|
|
15
|
+
function toServerRequest(req) {
|
|
16
|
+
const rawBody = Buffer.isBuffer(req.body)
|
|
17
|
+
? new Uint8Array(req.body.buffer, req.body.byteOffset, req.body.byteLength)
|
|
18
|
+
: undefined;
|
|
19
|
+
return {
|
|
20
|
+
method: req.method.toUpperCase(),
|
|
21
|
+
path: req.path,
|
|
22
|
+
params: req.params,
|
|
23
|
+
query: req.query,
|
|
24
|
+
headers: req.headers,
|
|
25
|
+
body: rawBody ? {} : req.body,
|
|
26
|
+
rawBody,
|
|
27
|
+
jsonBodyBytes: req.jsonBodyBytes,
|
|
28
|
+
httpVersion: req.httpVersion,
|
|
29
|
+
clientIp: req.ip,
|
|
30
|
+
tenantId: req.tenantId,
|
|
31
|
+
systemAdmin: req.systemAdmin,
|
|
32
|
+
syncPrincipal: req.syncPrincipal,
|
|
33
|
+
timestampPrincipal: req.timestampPrincipal,
|
|
34
|
+
peerName: req.peerName,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Copy what a guard resolved back onto the Express request for later middleware. */
|
|
38
|
+
function applyGuardResults(req, serverRequest) {
|
|
39
|
+
req.tenantId = serverRequest.tenantId;
|
|
40
|
+
req.systemAdmin = serverRequest.systemAdmin;
|
|
41
|
+
req.syncPrincipal = serverRequest.syncPrincipal;
|
|
42
|
+
req.timestampPrincipal = serverRequest.timestampPrincipal;
|
|
43
|
+
req.peerName = serverRequest.peerName;
|
|
44
|
+
}
|
|
45
|
+
/** Write a JSON or binary response. Event streams are the caller's business. */
|
|
46
|
+
async function sendServerResponse(req, res, response) {
|
|
47
|
+
if ((0, types_1.isJsonResponse)(response)) {
|
|
48
|
+
for (const [name, value] of Object.entries(response.headers ?? {})) {
|
|
49
|
+
res.setHeader(name, value);
|
|
50
|
+
}
|
|
51
|
+
res.status(response.status).json(response.json);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if ((0, types_1.isBytesResponse)(response)) {
|
|
55
|
+
for (const [name, value] of Object.entries(response.headers)) {
|
|
56
|
+
res.setHeader(name, value);
|
|
57
|
+
}
|
|
58
|
+
res.status(response.status);
|
|
59
|
+
if (response.binaryEntryFrameBytes !== undefined) {
|
|
60
|
+
await (0, compressionMiddleware_1.sendBinaryEntryBody)(req, res, response.bytes, response.binaryEntryFrameBytes);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const bytes = response.bytes;
|
|
64
|
+
res.send(Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
throw new Error("Event stream responses must be handled by the route");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Express route handler running a core handler. Anything the handler did not
|
|
71
|
+
* turn into a response goes to the Express error handler, as a throw from a
|
|
72
|
+
* synchronous handler would.
|
|
73
|
+
*/
|
|
74
|
+
function route(handler) {
|
|
75
|
+
return async (req, res, next) => {
|
|
76
|
+
try {
|
|
77
|
+
const response = await handler(toServerRequest(req));
|
|
78
|
+
await sendServerResponse(req, res, response);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
next(error);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Express middleware running a core guard: a returned response ends the
|
|
87
|
+
* request, null continues with the guard's results on the request.
|
|
88
|
+
*/
|
|
89
|
+
function guard(check) {
|
|
90
|
+
return async (req, res, next) => {
|
|
91
|
+
const serverRequest = toServerRequest(req);
|
|
92
|
+
let rejection;
|
|
93
|
+
try {
|
|
94
|
+
rejection = await check(serverRequest);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
next(error);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (rejection) {
|
|
101
|
+
await sendServerResponse(req, res, rejection);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
applyGuardResults(req, serverRequest);
|
|
105
|
+
next();
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=expressAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expressAdapter.js","sourceRoot":"","sources":["../../../src/node/server/expressAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type IrohStreamIO } from "../../core/appendonlystores/network/IrohStreamIO";
|
|
2
|
-
import type { ServerIrohConfig } from "
|
|
2
|
+
import type { ServerIrohConfig } from "../../server/types";
|
|
3
3
|
export interface NativeIrohStreamIO extends IrohStreamIO {
|
|
4
4
|
endpointId?: string;
|
|
5
5
|
close?(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeIrohStreamIO.d.ts","sourceRoot":"","sources":["../../../src/node/server/nativeIrohStreamIO.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,kDAAkD,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"nativeIrohStreamIO.d.ts","sourceRoot":"","sources":["../../../src/node/server/nativeIrohStreamIO.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,kDAAkD,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AA6BD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,cAAc,eAAe,CAAC,GAAG,IAAI,CAAC,CAM3F;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAwE7B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cluster audit log on disk: `<dataDir>/cluster/audit.jsonl`, rotated to
|
|
3
|
+
* `audit.jsonl.<timestamp>` once it passes {@link DEFAULT_MAX_BYTES}. Only the
|
|
4
|
+
* active file is read back.
|
|
5
|
+
*/
|
|
6
|
+
import type { ClusterAuditStorage } from "../../../server/peer/ClusterAuditLog";
|
|
7
|
+
export declare class FileClusterAuditStorage implements ClusterAuditStorage {
|
|
8
|
+
private readonly maxBytes;
|
|
9
|
+
private readonly dir;
|
|
10
|
+
private readonly file;
|
|
11
|
+
constructor(dataDir: string, maxBytes?: number);
|
|
12
|
+
appendLine(line: string): void;
|
|
13
|
+
readLines(): string[];
|
|
14
|
+
private rotateIfNeeded;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=FileClusterAuditStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileClusterAuditStorage.d.ts","sourceRoot":"","sources":["../../../../src/node/server/peer/FileClusterAuditStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAKhF,qBAAa,uBAAwB,YAAW,mBAAmB;IAM/D,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAL3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAG5B,OAAO,EAAE,MAAM,EACE,QAAQ,GAAE,MAA0B;IAMvD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM9B,SAAS,IAAI,MAAM,EAAE;IAKrB,OAAO,CAAC,cAAc;CAKvB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The cluster audit log on disk: `<dataDir>/cluster/audit.jsonl`, rotated to
|
|
4
|
+
* `audit.jsonl.<timestamp>` once it passes {@link DEFAULT_MAX_BYTES}. Only the
|
|
5
|
+
* active file is read back.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.FileClusterAuditStorage = void 0;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
/** Rotate once the active file passes this size. */
|
|
12
|
+
const DEFAULT_MAX_BYTES = 5 * 1024 * 1024;
|
|
13
|
+
class FileClusterAuditStorage {
|
|
14
|
+
constructor(dataDir, maxBytes = DEFAULT_MAX_BYTES) {
|
|
15
|
+
this.maxBytes = maxBytes;
|
|
16
|
+
this.dir = (0, path_1.join)(dataDir, "cluster");
|
|
17
|
+
this.file = (0, path_1.join)(this.dir, "audit.jsonl");
|
|
18
|
+
}
|
|
19
|
+
appendLine(line) {
|
|
20
|
+
if (!(0, fs_1.existsSync)(this.dir))
|
|
21
|
+
(0, fs_1.mkdirSync)(this.dir, { recursive: true });
|
|
22
|
+
this.rotateIfNeeded();
|
|
23
|
+
(0, fs_1.appendFileSync)(this.file, `${line}\n`, "utf8");
|
|
24
|
+
}
|
|
25
|
+
readLines() {
|
|
26
|
+
if (!(0, fs_1.existsSync)(this.file))
|
|
27
|
+
return [];
|
|
28
|
+
return (0, fs_1.readFileSync)(this.file, "utf8").split("\n");
|
|
29
|
+
}
|
|
30
|
+
rotateIfNeeded() {
|
|
31
|
+
if (!(0, fs_1.existsSync)(this.file))
|
|
32
|
+
return;
|
|
33
|
+
if ((0, fs_1.statSync)(this.file).size < this.maxBytes)
|
|
34
|
+
return;
|
|
35
|
+
(0, fs_1.renameSync)(this.file, `${this.file}.${Date.now()}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.FileClusterAuditStorage = FileClusterAuditStorage;
|
|
39
|
+
//# sourceMappingURL=FileClusterAuditStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileClusterAuditStorage.js","sourceRoot":"","sources":["../../../../src/node/server/peer/FileClusterAuditStorage.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,2BAA+F;AAC/F,+BAA4B;AAI5B,oDAAoD;AACpD,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1C,MAAa,uBAAuB;IAIlC,YACE,OAAe,EACE,WAAmB,iBAAiB;QAApC,aAAQ,GAAR,QAAQ,CAA4B;QAErD,IAAI,CAAC,GAAG,GAAG,IAAA,WAAI,EAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,GAAG,CAAC;YAAE,IAAA,cAAS,EAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAA,mBAAc,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,SAAS;QACP,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QACtC,OAAO,IAAA,iBAAY,EAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO;QACnC,IAAI,IAAA,aAAQ,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ;YAAE,OAAO;QACrD,IAAA,eAAU,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC;CACF;AA5BD,0DA4BC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* change feed share the handshake; each in-flight call still owns its stream.
|
|
4
4
|
*/
|
|
5
5
|
import { type IrohByteStream, type IrohRpcContext, type IrohStreamIO } from "../../../core/appendonlystores/network/IrohStreamIO";
|
|
6
|
-
import type { SyncChangeEvent } from "
|
|
6
|
+
import type { SyncChangeEvent } from "../../../server/SyncEventBus";
|
|
7
7
|
export declare class IrohPeerLink {
|
|
8
8
|
private readonly io;
|
|
9
9
|
private readonly ticket;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IrohPeerLink.d.ts","sourceRoot":"","sources":["../../../../src/node/server/peer/IrohPeerLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIL,KAAK,cAAc,EAEnB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,qDAAqD,CAAC;AAI7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"IrohPeerLink.d.ts","sourceRoot":"","sources":["../../../../src/node/server/peer/IrohPeerLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIL,KAAK,cAAc,EAEnB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,qDAAqD,CAAC;AAI7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,qBAAa,YAAY;IAKrB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,MAAM,CAAK;gBAGA,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,MAAM;YAGnB,gBAAgB;IAUxB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAUlF;;;OAGG;IACH,UAAU,IAAI,YAAY;IAWpB,eAAe,CACnB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,EACzC,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,IAAI,CAAC;IA4CV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B;AAkBD,YAAY,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -1,37 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTTP surface
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* protocol. Callers authenticate as a server listed in
|
|
6
|
-
* `trusted-servers.json` and receive a peer JWT. No route here can
|
|
7
|
-
* administer anything.
|
|
8
|
-
* - {@link createClusterRouter} serves `/system/cluster/*`: the admin surface
|
|
9
|
-
* for humans and consoles. Callers authenticate with a system-admin JWT and
|
|
10
|
-
* pass the {@link CapabilityMatcher}. No route here can write entries.
|
|
11
|
-
*
|
|
12
|
-
* The split is the point. A peer must be able to replicate without being able
|
|
13
|
-
* to reconfigure the node it replicates with, and an operator must be able to
|
|
14
|
-
* administer without being able to forge data as a server identity.
|
|
15
|
-
*
|
|
16
|
-
* ## Fan-out, not proxy
|
|
17
|
-
*
|
|
18
|
-
* Every read endpoint answers for **this node only**. A console that wants a
|
|
19
|
-
* cluster-wide view calls each node in turn and merges. The alternative — one
|
|
20
|
-
* node proxying admin reads to its peers — would need an admin credential that
|
|
21
|
-
* spans servers, and peers are separately administered by design: they trust
|
|
22
|
-
* each other with encrypted data, not with each other's administration.
|
|
23
|
-
*
|
|
24
|
-
* ## Admin-blindness
|
|
25
|
-
*
|
|
26
|
-
* Nothing here returns a document id, an author key, or entry content. Status,
|
|
27
|
-
* jobs and audit records carry counts, tenant/database ids and classified
|
|
28
|
-
* reasons. A read-only auditor role must not become a metadata oracle over
|
|
29
|
-
* data the server itself cannot decrypt.
|
|
2
|
+
* Express mounting of the cluster HTTP surface. The handlers, and the
|
|
3
|
+
* reasoning behind the split into `/system/peer/*` (server-to-server) and
|
|
4
|
+
* `/system/cluster/*` (administration), live in `server/peer/clusterHttp.ts`.
|
|
30
5
|
*/
|
|
31
6
|
import { Router } from "express";
|
|
32
|
-
import type { SyncEventBus } from "
|
|
33
|
-
import type { ClusterManager } from "
|
|
34
|
-
import type
|
|
7
|
+
import type { SyncEventBus } from "../../../server/SyncEventBus";
|
|
8
|
+
import type { ClusterManager } from "../../../server/peer/ClusterManager";
|
|
9
|
+
import { type ClusterAdminDeps } from "../../../server/peer/clusterHttp";
|
|
35
10
|
declare global {
|
|
36
11
|
namespace Express {
|
|
37
12
|
interface Request {
|
|
@@ -44,23 +19,14 @@ export interface PeerRouterDeps {
|
|
|
44
19
|
cluster: ClusterManager;
|
|
45
20
|
eventBus: SyncEventBus;
|
|
46
21
|
listTenants(): string[];
|
|
47
|
-
listDatabases(tenantId: string): string[]
|
|
22
|
+
listDatabases(tenantId: string): string[] | Promise<string[]>;
|
|
48
23
|
}
|
|
49
24
|
export declare function createPeerRouter(deps: PeerRouterDeps): Router;
|
|
50
|
-
export
|
|
51
|
-
cluster: ClusterManager;
|
|
52
|
-
/** Read `trusted-servers.json`; used by peer CRUD. */
|
|
53
|
-
listTrustedServers(): TrustedServer[];
|
|
54
|
-
/** Persist a peer entry (add or replace by name). */
|
|
55
|
-
saveTrustedServer(peer: TrustedServer): void;
|
|
56
|
-
/** Remove a peer entry by name; false when it did not exist. */
|
|
57
|
-
removeTrustedServer(name: string): boolean;
|
|
58
|
-
}
|
|
25
|
+
export type ClusterRouterDeps = ClusterAdminDeps;
|
|
59
26
|
/**
|
|
60
27
|
* Admin surface. The caller mounts this behind the system-admin JWT
|
|
61
|
-
* middleware, so capability rules in `config.json` decide who may read
|
|
62
|
-
*
|
|
63
|
-
* that is how an auditor role gets status without getting control.
|
|
28
|
+
* middleware, so capability rules in `config.json` decide who may read and
|
|
29
|
+
* who may act.
|
|
64
30
|
*/
|
|
65
31
|
export declare function createClusterRouter(deps: ClusterRouterDeps): Router;
|
|
66
32
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../../src/node/server/peer/routes.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../../src/node/server/peer/routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,kCAAkC,CAAC;AAI1C,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,qEAAqE;YACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB;KACF;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC/D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAmD7D;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAiBnE"}
|
|
@@ -1,126 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* HTTP surface
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* protocol. Callers authenticate as a server listed in
|
|
7
|
-
* `trusted-servers.json` and receive a peer JWT. No route here can
|
|
8
|
-
* administer anything.
|
|
9
|
-
* - {@link createClusterRouter} serves `/system/cluster/*`: the admin surface
|
|
10
|
-
* for humans and consoles. Callers authenticate with a system-admin JWT and
|
|
11
|
-
* pass the {@link CapabilityMatcher}. No route here can write entries.
|
|
12
|
-
*
|
|
13
|
-
* The split is the point. A peer must be able to replicate without being able
|
|
14
|
-
* to reconfigure the node it replicates with, and an operator must be able to
|
|
15
|
-
* administer without being able to forge data as a server identity.
|
|
16
|
-
*
|
|
17
|
-
* ## Fan-out, not proxy
|
|
18
|
-
*
|
|
19
|
-
* Every read endpoint answers for **this node only**. A console that wants a
|
|
20
|
-
* cluster-wide view calls each node in turn and merges. The alternative — one
|
|
21
|
-
* node proxying admin reads to its peers — would need an admin credential that
|
|
22
|
-
* spans servers, and peers are separately administered by design: they trust
|
|
23
|
-
* each other with encrypted data, not with each other's administration.
|
|
24
|
-
*
|
|
25
|
-
* ## Admin-blindness
|
|
26
|
-
*
|
|
27
|
-
* Nothing here returns a document id, an author key, or entry content. Status,
|
|
28
|
-
* jobs and audit records carry counts, tenant/database ids and classified
|
|
29
|
-
* reasons. A read-only auditor role must not become a metadata oracle over
|
|
30
|
-
* data the server itself cannot decrypt.
|
|
3
|
+
* Express mounting of the cluster HTTP surface. The handlers, and the
|
|
4
|
+
* reasoning behind the split into `/system/peer/*` (server-to-server) and
|
|
5
|
+
* `/system/cluster/*` (administration), live in `server/peer/clusterHttp.ts`.
|
|
31
6
|
*/
|
|
32
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
8
|
exports.createPeerRouter = createPeerRouter;
|
|
34
9
|
exports.createClusterRouter = createClusterRouter;
|
|
35
10
|
const express_1 = require("express");
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const MAX_BLOOM_BITS = 1 << 22;
|
|
11
|
+
const clusterHttp_1 = require("../../../server/peer/clusterHttp");
|
|
12
|
+
const MindooDBServerCore_1 = require("../../../server/http/MindooDBServerCore");
|
|
13
|
+
const expressAdapter_1 = require("../expressAdapter");
|
|
40
14
|
function createPeerRouter(deps) {
|
|
41
15
|
const router = (0, express_1.Router)();
|
|
42
|
-
const
|
|
43
|
-
const requirePeer =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
const payload = await cluster.auth.validateToken(auth.substring(7));
|
|
50
|
-
if (!payload) {
|
|
51
|
-
res.status(401).json({ error: "Invalid or expired peer token" });
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
req.peerName = payload.sub;
|
|
55
|
-
next();
|
|
56
|
-
};
|
|
57
|
-
router.post("/challenge", async (req, res) => {
|
|
58
|
-
const { publicsignkey } = req.body;
|
|
59
|
-
if (typeof publicsignkey !== "string" || publicsignkey.length === 0) {
|
|
60
|
-
res.status(400).json({ error: "publicsignkey is required" });
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
res.json({ challenge: await cluster.auth.generateChallenge(publicsignkey) });
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
// Deliberately the same shape as a signature failure: an unauthenticated
|
|
68
|
-
// caller must not be able to enumerate which servers we trust.
|
|
69
|
-
res.status(401).json({ error: "Unknown peer" });
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
router.post("/authenticate", async (req, res) => {
|
|
73
|
-
const { challenge, signature } = req.body;
|
|
74
|
-
if (typeof challenge !== "string" || typeof signature !== "string") {
|
|
75
|
-
res.status(400).json({ error: "challenge and signature are required" });
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const result = await cluster.auth.authenticate(challenge, new Uint8Array(Buffer.from(signature, "base64")));
|
|
79
|
-
if (!result.success) {
|
|
80
|
-
res.status(401).json({ error: result.error ?? "Authentication failed" });
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
res.json({ success: true, token: result.token });
|
|
84
|
-
});
|
|
85
|
-
/**
|
|
86
|
-
* Tenant intersection.
|
|
87
|
-
*
|
|
88
|
-
* The caller sends a Bloom summary of the tenants it hosts; we answer with
|
|
89
|
-
* the ids on *our* side that the filter might contain. Neither server ever
|
|
90
|
-
* transmits its full tenant list, so a peer learns nothing about tenants it
|
|
91
|
-
* does not already host. False positives are harmless: the caller intersects
|
|
92
|
-
* the answer against its own authoritative list before replicating anything.
|
|
93
|
-
*/
|
|
94
|
-
router.post("/tenant-bloom", requirePeer, (req, res) => {
|
|
95
|
-
const { bloom } = req.body;
|
|
96
|
-
if (!bloom || typeof bloom !== "object") {
|
|
97
|
-
res.status(400).json({ error: "bloom summary is required" });
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (typeof bloom.bitCount !== "number" || bloom.bitCount <= 0 || bloom.bitCount > MAX_BLOOM_BITS) {
|
|
101
|
-
res.status(400).json({ error: "Invalid bloom summary" });
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
const candidates = deps
|
|
105
|
-
.listTenants()
|
|
106
|
-
.filter((tenantId) => (0, bloom_1.bloomMightContainId)(bloom, tenantId));
|
|
107
|
-
// Remember what this peer may see, so the event stream can be filtered to
|
|
108
|
-
// the same set instead of announcing every tenant we host.
|
|
109
|
-
cluster.recordPeerIntersection(req.peerName, candidates);
|
|
110
|
-
res.json({ tenantIds: candidates });
|
|
111
|
-
});
|
|
112
|
-
router.get("/databases", requirePeer, (req, res) => {
|
|
113
|
-
const tenantId = typeof req.query.tenantId === "string" ? req.query.tenantId : "";
|
|
114
|
-
if (!tenantId) {
|
|
115
|
-
res.status(400).json({ error: "tenantId is required" });
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (!cluster.peerMaySeeTenant(req.peerName, tenantId)) {
|
|
119
|
-
res.status(404).json({ error: "Tenant not found" });
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
res.json({ databases: deps.listDatabases(tenantId) });
|
|
123
|
-
});
|
|
16
|
+
const handlers = new clusterHttp_1.PeerHttpHandlers(deps);
|
|
17
|
+
const requirePeer = (0, expressAdapter_1.guard)((req) => handlers.peerGuard(req));
|
|
18
|
+
router.post("/challenge", (0, expressAdapter_1.route)((req) => handlers.challenge(req)));
|
|
19
|
+
router.post("/authenticate", (0, expressAdapter_1.route)((req) => handlers.authenticate(req)));
|
|
20
|
+
router.post("/tenant-bloom", requirePeer, (0, expressAdapter_1.route)((req) => handlers.tenantBloom(req)));
|
|
21
|
+
router.get("/databases", requirePeer, (0, expressAdapter_1.route)((req) => handlers.databases(req)));
|
|
124
22
|
/**
|
|
125
23
|
* Change feed for peers, across every shared tenant.
|
|
126
24
|
*
|
|
@@ -139,26 +37,15 @@ function createPeerRouter(deps) {
|
|
|
139
37
|
res.setHeader("Connection", "keep-alive");
|
|
140
38
|
}
|
|
141
39
|
res.flushHeaders();
|
|
142
|
-
res.write(
|
|
40
|
+
res.write((0, MindooDBServerCore_1.formatSyncHelloEvent)());
|
|
143
41
|
const unsubscribe = deps.eventBus.subscribe((event) => {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (event.originPeer === peerName)
|
|
148
|
-
return;
|
|
149
|
-
if (!cluster.peerMaySeeTenant(peerName, event.tenantId))
|
|
150
|
-
return;
|
|
151
|
-
res.write(`event: change\ndata: ${JSON.stringify({
|
|
152
|
-
tenantId: event.tenantId,
|
|
153
|
-
dbId: event.dbId,
|
|
154
|
-
storeKind: event.storeKind,
|
|
155
|
-
epoch: event.epoch,
|
|
156
|
-
maxReceiptOrder: event.maxReceiptOrder,
|
|
157
|
-
})}\n\n`);
|
|
42
|
+
const frame = (0, clusterHttp_1.formatPeerChangeEvent)(deps.cluster, peerName, event);
|
|
43
|
+
if (frame)
|
|
44
|
+
res.write(frame);
|
|
158
45
|
});
|
|
159
46
|
const heartbeat = setInterval(() => {
|
|
160
|
-
res.write(
|
|
161
|
-
},
|
|
47
|
+
res.write((0, MindooDBServerCore_1.formatSyncHeartbeat)(Date.now()));
|
|
48
|
+
}, MindooDBServerCore_1.SYNC_EVENT_HEARTBEAT_MS);
|
|
162
49
|
const cleanup = () => {
|
|
163
50
|
clearInterval(heartbeat);
|
|
164
51
|
unsubscribe();
|
|
@@ -166,157 +53,28 @@ function createPeerRouter(deps) {
|
|
|
166
53
|
req.on("close", cleanup);
|
|
167
54
|
res.on("close", cleanup);
|
|
168
55
|
});
|
|
169
|
-
|
|
170
|
-
* Catch-up trigger from the calling peer.
|
|
171
|
-
*
|
|
172
|
-
* Peer A tells us "I have something for you"; we run our own replicator
|
|
173
|
-
* toward A, which pulls it. Doing it this way rather than having A push
|
|
174
|
-
* directly keeps one replicator per link in charge of cursors and ordering,
|
|
175
|
-
* so the invariants hold no matter which side noticed the change first.
|
|
176
|
-
*/
|
|
177
|
-
router.post("/sync", requirePeer, (req, res) => {
|
|
178
|
-
const peerName = req.peerName;
|
|
179
|
-
const replicator = cluster.getReplicator(peerName);
|
|
180
|
-
if (!replicator) {
|
|
181
|
-
res.status(409).json({
|
|
182
|
-
error: `No outbound session configured for peer ${peerName} (missing url in trusted-servers.json)`,
|
|
183
|
-
});
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
const { tenantId, dbId } = (req.body ?? {});
|
|
187
|
-
// Fire and forget: the caller only needs to know we accepted the hint, and
|
|
188
|
-
// holding the connection open for a full mirror would time out.
|
|
189
|
-
void replicator.syncNow({ tenantId, dbId }).catch(() => undefined);
|
|
190
|
-
res.status(202).json({ accepted: true });
|
|
191
|
-
});
|
|
56
|
+
router.post("/sync", requirePeer, (0, expressAdapter_1.route)((req) => handlers.sync(req)));
|
|
192
57
|
return router;
|
|
193
58
|
}
|
|
194
|
-
const ACTION_KINDS = {
|
|
195
|
-
sync: "sync",
|
|
196
|
-
"retry-rejected": "retry-rejected",
|
|
197
|
-
"refresh-intersection": "refresh-intersection",
|
|
198
|
-
pause: "pause",
|
|
199
|
-
resume: "resume",
|
|
200
|
-
};
|
|
201
59
|
/**
|
|
202
60
|
* Admin surface. The caller mounts this behind the system-admin JWT
|
|
203
|
-
* middleware, so capability rules in `config.json` decide who may read
|
|
204
|
-
*
|
|
205
|
-
* that is how an auditor role gets status without getting control.
|
|
61
|
+
* middleware, so capability rules in `config.json` decide who may read and
|
|
62
|
+
* who may act.
|
|
206
63
|
*/
|
|
207
64
|
function createClusterRouter(deps) {
|
|
208
65
|
const router = (0, express_1.Router)();
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
router.get("/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
router.get("/
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
router.get("/
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
router.
|
|
221
|
-
const limit = Number.parseInt(String(req.query.limit ?? "50"), 10);
|
|
222
|
-
res.json({ jobs: cluster.jobs.list(Number.isFinite(limit) ? limit : 50) });
|
|
223
|
-
});
|
|
224
|
-
router.get("/jobs/:jobId", (req, res) => {
|
|
225
|
-
const job = cluster.jobs.get(req.params.jobId);
|
|
226
|
-
if (!job) {
|
|
227
|
-
res.status(404).json({ error: "Job not found" });
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
res.json(job);
|
|
231
|
-
});
|
|
232
|
-
router.get("/audit", (req, res) => {
|
|
233
|
-
const limit = Number.parseInt(String(req.query.limit ?? "50"), 10);
|
|
234
|
-
const before = typeof req.query.before === "string" ? req.query.before : undefined;
|
|
235
|
-
res.json(cluster.audit.read({ limit: Number.isFinite(limit) ? limit : 50, before }));
|
|
236
|
-
});
|
|
237
|
-
router.post("/actions/:action", (req, res) => {
|
|
238
|
-
const kind = ACTION_KINDS[req.params.action];
|
|
239
|
-
if (!kind) {
|
|
240
|
-
res.status(404).json({ error: `Unknown action: ${req.params.action}` });
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
const body = (req.body ?? {});
|
|
244
|
-
const scope = {
|
|
245
|
-
peer: typeof body.peer === "string" ? body.peer : undefined,
|
|
246
|
-
tenantId: typeof body.tenantId === "string" ? body.tenantId.toLowerCase() : undefined,
|
|
247
|
-
dbId: typeof body.dbId === "string" ? body.dbId : undefined,
|
|
248
|
-
};
|
|
249
|
-
const outcome = cluster.runAction(kind, scope, actor(req));
|
|
250
|
-
if (!outcome.accepted) {
|
|
251
|
-
res.status(400).json({ error: outcome.error });
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
// 202: the job is queued, not finished. Poll GET /jobs/:jobId.
|
|
255
|
-
res.status(202).json({ jobId: outcome.job.id, job: outcome.job });
|
|
256
|
-
});
|
|
257
|
-
router.get("/peers", (_req, res) => {
|
|
258
|
-
res.json({ peers: cluster.topology().peers });
|
|
259
|
-
});
|
|
260
|
-
router.post("/peers/:name", (req, res) => {
|
|
261
|
-
upsertPeer(req, res, deps, "peer-create");
|
|
262
|
-
});
|
|
263
|
-
router.patch("/peers/:name", (req, res) => {
|
|
264
|
-
upsertPeer(req, res, deps, "peer-update");
|
|
265
|
-
});
|
|
266
|
-
router.delete("/peers/:name", (req, res) => {
|
|
267
|
-
const name = decodeURIComponent(req.params.name);
|
|
268
|
-
if (!deps.removeTrustedServer(name)) {
|
|
269
|
-
res.status(404).json({ error: "Peer not found" });
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
cluster.syncReplicators();
|
|
273
|
-
cluster.auditPeerChange("peer-delete", name, actor(req));
|
|
274
|
-
res.json({ success: true });
|
|
275
|
-
});
|
|
66
|
+
const handlers = new clusterHttp_1.ClusterAdminHandlers(deps);
|
|
67
|
+
router.get("/topology", (0, expressAdapter_1.route)(() => handlers.topology()));
|
|
68
|
+
router.get("/status", (0, expressAdapter_1.route)(() => handlers.status()));
|
|
69
|
+
router.get("/status/tenants/:tenantId", (0, expressAdapter_1.route)((req) => handlers.tenantStatus(req)));
|
|
70
|
+
router.get("/jobs", (0, expressAdapter_1.route)((req) => handlers.jobs(req)));
|
|
71
|
+
router.get("/jobs/:jobId", (0, expressAdapter_1.route)((req) => handlers.job(req)));
|
|
72
|
+
router.get("/audit", (0, expressAdapter_1.route)((req) => handlers.audit(req)));
|
|
73
|
+
router.post("/actions/:action", (0, expressAdapter_1.route)((req) => handlers.action(req)));
|
|
74
|
+
router.get("/peers", (0, expressAdapter_1.route)(() => handlers.peers()));
|
|
75
|
+
router.post("/peers/:name", (0, expressAdapter_1.route)((req) => handlers.createPeer(req)));
|
|
76
|
+
router.patch("/peers/:name", (0, expressAdapter_1.route)((req) => handlers.updatePeer(req)));
|
|
77
|
+
router.delete("/peers/:name", (0, expressAdapter_1.route)((req) => handlers.deletePeer(req)));
|
|
276
78
|
return router;
|
|
277
79
|
}
|
|
278
|
-
function upsertPeer(req, res, deps, action) {
|
|
279
|
-
const name = decodeURIComponent(req.params.name);
|
|
280
|
-
const existing = deps.listTrustedServers().find((peer) => peer.name === name);
|
|
281
|
-
if (action === "peer-create" && existing) {
|
|
282
|
-
res.status(409).json({ error: "Peer already exists" });
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
if (action === "peer-update" && !existing) {
|
|
286
|
-
res.status(404).json({ error: "Peer not found" });
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const body = req.body;
|
|
290
|
-
const signingPublicKey = body.signingPublicKey ?? existing?.signingPublicKey;
|
|
291
|
-
const encryptionPublicKey = body.encryptionPublicKey ?? existing?.encryptionPublicKey;
|
|
292
|
-
if (!signingPublicKey || !encryptionPublicKey) {
|
|
293
|
-
res.status(400).json({ error: "signingPublicKey and encryptionPublicKey are required" });
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
for (const [field, guard] of [
|
|
297
|
-
["direction", types_1.isPeerSyncDirection],
|
|
298
|
-
["role", types_1.isPeerRole],
|
|
299
|
-
["attachments", types_1.isPeerAttachmentMode],
|
|
300
|
-
]) {
|
|
301
|
-
const value = body[field];
|
|
302
|
-
if (value !== undefined && !guard(value)) {
|
|
303
|
-
res.status(400).json({ error: `Invalid ${field}: ${String(value)}` });
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
const peer = {
|
|
308
|
-
...existing,
|
|
309
|
-
name,
|
|
310
|
-
signingPublicKey,
|
|
311
|
-
encryptionPublicKey,
|
|
312
|
-
url: body.url ?? existing?.url,
|
|
313
|
-
direction: body.direction ?? existing?.direction,
|
|
314
|
-
role: body.role ?? existing?.role,
|
|
315
|
-
attachments: body.attachments ?? existing?.attachments,
|
|
316
|
-
};
|
|
317
|
-
deps.saveTrustedServer(peer);
|
|
318
|
-
deps.cluster.syncReplicators();
|
|
319
|
-
deps.cluster.auditPeerChange(action, name, req.systemAdmin?.username ?? "unknown");
|
|
320
|
-
res.status(action === "peer-create" ? 201 : 200).json({ success: true, peer });
|
|
321
|
-
}
|
|
322
80
|
//# sourceMappingURL=routes.js.map
|