@brightchain/brightchain-api-lib 0.13.0 → 0.15.0
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/package.json +5 -5
- package/src/index.d.ts +3 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +5 -0
- package/src/index.js.map +1 -1
- package/src/lib/application.d.ts +1 -0
- package/src/lib/application.d.ts.map +1 -1
- package/src/lib/application.js +23 -0
- package/src/lib/application.js.map +1 -1
- package/src/lib/auth/aclEnforcedAvailability.d.ts +57 -0
- package/src/lib/auth/aclEnforcedAvailability.d.ts.map +1 -0
- package/src/lib/auth/aclEnforcedAvailability.js +87 -0
- package/src/lib/auth/aclEnforcedAvailability.js.map +1 -0
- package/src/lib/auth/aclEnforcedBlockStore.d.ts +66 -0
- package/src/lib/auth/aclEnforcedBlockStore.d.ts.map +1 -0
- package/src/lib/auth/aclEnforcedBlockStore.js +83 -0
- package/src/lib/auth/aclEnforcedBlockStore.js.map +1 -0
- package/src/lib/auth/ecdsaNodeAuthenticator.d.ts +46 -0
- package/src/lib/auth/ecdsaNodeAuthenticator.d.ts.map +1 -0
- package/src/lib/auth/ecdsaNodeAuthenticator.js +110 -0
- package/src/lib/auth/ecdsaNodeAuthenticator.js.map +1 -0
- package/src/lib/auth/index.d.ts +7 -0
- package/src/lib/auth/index.d.ts.map +1 -0
- package/src/lib/auth/index.js +13 -0
- package/src/lib/auth/index.js.map +1 -0
- package/src/lib/auth/poolAclBootstrap.d.ts +36 -0
- package/src/lib/auth/poolAclBootstrap.d.ts.map +1 -0
- package/src/lib/auth/poolAclBootstrap.js +64 -0
- package/src/lib/auth/poolAclBootstrap.js.map +1 -0
- package/src/lib/auth/poolAclStore.d.ts +77 -0
- package/src/lib/auth/poolAclStore.d.ts.map +1 -0
- package/src/lib/auth/poolAclStore.js +189 -0
- package/src/lib/auth/poolAclStore.js.map +1 -0
- package/src/lib/auth/poolAclUpdater.d.ts +79 -0
- package/src/lib/auth/poolAclUpdater.d.ts.map +1 -0
- package/src/lib/auth/poolAclUpdater.js +144 -0
- package/src/lib/auth/poolAclUpdater.js.map +1 -0
- package/src/lib/availability/availabilityService.d.ts +2 -2
- package/src/lib/availability/availabilityService.d.ts.map +1 -1
- package/src/lib/availability/availabilityService.js +12 -5
- package/src/lib/availability/availabilityService.js.map +1 -1
- package/src/lib/availability/blockRegistry.d.ts +45 -3
- package/src/lib/availability/blockRegistry.d.ts.map +1 -1
- package/src/lib/availability/blockRegistry.js +123 -5
- package/src/lib/availability/blockRegistry.js.map +1 -1
- package/src/lib/availability/configValidation.d.ts.map +1 -1
- package/src/lib/availability/configValidation.js +20 -0
- package/src/lib/availability/configValidation.js.map +1 -1
- package/src/lib/availability/discoveryProtocol.d.ts +30 -1
- package/src/lib/availability/discoveryProtocol.d.ts.map +1 -1
- package/src/lib/availability/discoveryProtocol.js +76 -0
- package/src/lib/availability/discoveryProtocol.js.map +1 -1
- package/src/lib/availability/gossipService.d.ts +193 -11
- package/src/lib/availability/gossipService.d.ts.map +1 -1
- package/src/lib/availability/gossipService.js +473 -21
- package/src/lib/availability/gossipService.js.map +1 -1
- package/src/lib/availability/reconciliationService.d.ts +88 -1
- package/src/lib/availability/reconciliationService.d.ts.map +1 -1
- package/src/lib/availability/reconciliationService.js +246 -48
- package/src/lib/availability/reconciliationService.js.map +1 -1
- package/src/lib/blockFetch/blockFetcher.d.ts +100 -0
- package/src/lib/blockFetch/blockFetcher.d.ts.map +1 -0
- package/src/lib/blockFetch/blockFetcher.js +279 -0
- package/src/lib/blockFetch/blockFetcher.js.map +1 -0
- package/src/lib/blockFetch/fetchQueue.d.ts +88 -0
- package/src/lib/blockFetch/fetchQueue.d.ts.map +1 -0
- package/src/lib/blockFetch/fetchQueue.js +204 -0
- package/src/lib/blockFetch/fetchQueue.js.map +1 -0
- package/src/lib/blockFetch/httpBlockFetchTransport.d.ts +65 -0
- package/src/lib/blockFetch/httpBlockFetchTransport.d.ts.map +1 -0
- package/src/lib/blockFetch/httpBlockFetchTransport.js +104 -0
- package/src/lib/blockFetch/httpBlockFetchTransport.js.map +1 -0
- package/src/lib/blockFetch/index.d.ts +10 -0
- package/src/lib/blockFetch/index.d.ts.map +1 -0
- package/src/lib/blockFetch/index.js +13 -0
- package/src/lib/blockFetch/index.js.map +1 -0
- package/src/lib/controllers/api/brightpass.d.ts +72 -0
- package/src/lib/controllers/api/brightpass.d.ts.map +1 -0
- package/src/lib/controllers/api/brightpass.js +577 -0
- package/src/lib/controllers/api/brightpass.js.map +1 -0
- package/src/lib/controllers/api/channels.d.ts +122 -0
- package/src/lib/controllers/api/channels.d.ts.map +1 -0
- package/src/lib/controllers/api/channels.js +701 -0
- package/src/lib/controllers/api/channels.js.map +1 -0
- package/src/lib/controllers/api/conversations.d.ts +89 -0
- package/src/lib/controllers/api/conversations.d.ts.map +1 -0
- package/src/lib/controllers/api/conversations.js +259 -0
- package/src/lib/controllers/api/conversations.js.map +1 -0
- package/src/lib/controllers/api/emails.d.ts +122 -0
- package/src/lib/controllers/api/emails.d.ts.map +1 -0
- package/src/lib/controllers/api/emails.js +494 -0
- package/src/lib/controllers/api/emails.js.map +1 -0
- package/src/lib/controllers/api/explodingMessages.d.ts +79 -0
- package/src/lib/controllers/api/explodingMessages.d.ts.map +1 -0
- package/src/lib/controllers/api/explodingMessages.js +378 -0
- package/src/lib/controllers/api/explodingMessages.js.map +1 -0
- package/src/lib/controllers/api/groups.d.ts +94 -0
- package/src/lib/controllers/api/groups.d.ts.map +1 -0
- package/src/lib/controllers/api/groups.js +484 -0
- package/src/lib/controllers/api/groups.js.map +1 -0
- package/src/lib/controllers/api/index.d.ts +6 -0
- package/src/lib/controllers/api/index.d.ts.map +1 -1
- package/src/lib/controllers/api/index.js +6 -0
- package/src/lib/controllers/api/index.js.map +1 -1
- package/src/lib/controllers/api/messages.d.ts.map +1 -1
- package/src/lib/controllers/api/messages.js +2 -1
- package/src/lib/controllers/api/messages.js.map +1 -1
- package/src/lib/controllers/api/sync.d.ts +38 -2
- package/src/lib/controllers/api/sync.d.ts.map +1 -1
- package/src/lib/controllers/api/sync.js +89 -0
- package/src/lib/controllers/api/sync.js.map +1 -1
- package/src/lib/controllers/crypto/gitController.d.ts +70 -0
- package/src/lib/controllers/crypto/gitController.d.ts.map +1 -0
- package/src/lib/controllers/crypto/gitController.js +306 -0
- package/src/lib/controllers/crypto/gitController.js.map +1 -0
- package/src/lib/controllers/crypto/index.d.ts +3 -0
- package/src/lib/controllers/crypto/index.d.ts.map +1 -0
- package/src/lib/controllers/crypto/index.js +6 -0
- package/src/lib/controllers/crypto/index.js.map +1 -0
- package/src/lib/controllers/crypto/walletController.d.ts +64 -0
- package/src/lib/controllers/crypto/walletController.d.ts.map +1 -0
- package/src/lib/controllers/crypto/walletController.js +260 -0
- package/src/lib/controllers/crypto/walletController.js.map +1 -0
- package/src/lib/controllers/identity/deviceController.d.ts +96 -0
- package/src/lib/controllers/identity/deviceController.d.ts.map +1 -0
- package/src/lib/controllers/identity/deviceController.js +355 -0
- package/src/lib/controllers/identity/deviceController.js.map +1 -0
- package/src/lib/controllers/identity/directoryController.d.ts +75 -0
- package/src/lib/controllers/identity/directoryController.d.ts.map +1 -0
- package/src/lib/controllers/identity/directoryController.js +288 -0
- package/src/lib/controllers/identity/directoryController.js.map +1 -0
- package/src/lib/controllers/identity/identityProofController.d.ts +94 -0
- package/src/lib/controllers/identity/identityProofController.d.ts.map +1 -0
- package/src/lib/controllers/identity/identityProofController.js +454 -0
- package/src/lib/controllers/identity/identityProofController.js.map +1 -0
- package/src/lib/controllers/identity/index.d.ts +4 -0
- package/src/lib/controllers/identity/index.d.ts.map +1 -0
- package/src/lib/controllers/identity/index.js +7 -0
- package/src/lib/controllers/identity/index.js.map +1 -0
- package/src/lib/controllers/index.d.ts +2 -0
- package/src/lib/controllers/index.d.ts.map +1 -1
- package/src/lib/controllers/index.js +2 -0
- package/src/lib/controllers/index.js.map +1 -1
- package/src/lib/encryption/encryptedMetadataService.d.ts +87 -0
- package/src/lib/encryption/encryptedMetadataService.d.ts.map +1 -0
- package/src/lib/encryption/encryptedMetadataService.js +224 -0
- package/src/lib/encryption/encryptedMetadataService.js.map +1 -0
- package/src/lib/encryption/encryptionAwareReplication.d.ts +76 -0
- package/src/lib/encryption/encryptionAwareReplication.d.ts.map +1 -0
- package/src/lib/encryption/encryptionAwareReplication.js +116 -0
- package/src/lib/encryption/encryptionAwareReplication.js.map +1 -0
- package/src/lib/encryption/errors.d.ts +49 -0
- package/src/lib/encryption/errors.d.ts.map +1 -0
- package/src/lib/encryption/errors.js +80 -0
- package/src/lib/encryption/errors.js.map +1 -0
- package/src/lib/encryption/index.d.ts +6 -0
- package/src/lib/encryption/index.d.ts.map +1 -0
- package/src/lib/encryption/index.js +9 -0
- package/src/lib/encryption/index.js.map +1 -0
- package/src/lib/encryption/poolEncryptionService.d.ts +94 -0
- package/src/lib/encryption/poolEncryptionService.d.ts.map +1 -0
- package/src/lib/encryption/poolEncryptionService.js +252 -0
- package/src/lib/encryption/poolEncryptionService.js.map +1 -0
- package/src/lib/encryption/poolKeyManager.d.ts +82 -0
- package/src/lib/encryption/poolKeyManager.d.ts.map +1 -0
- package/src/lib/encryption/poolKeyManager.js +156 -0
- package/src/lib/encryption/poolKeyManager.js.map +1 -0
- package/src/lib/environment.d.ts +3 -0
- package/src/lib/environment.d.ts.map +1 -1
- package/src/lib/environment.js +5 -0
- package/src/lib/environment.js.map +1 -1
- package/src/lib/interfaces/environment.d.ts +7 -1
- package/src/lib/interfaces/environment.d.ts.map +1 -1
- package/src/lib/interfaces/index.d.ts +0 -1
- package/src/lib/interfaces/index.d.ts.map +1 -1
- package/src/lib/interfaces/requests/getBlockDataRequest.d.ts +12 -0
- package/src/lib/interfaces/requests/getBlockDataRequest.d.ts.map +1 -0
- package/src/lib/interfaces/{blockStore.js → requests/getBlockDataRequest.js} +1 -1
- package/src/lib/interfaces/requests/getBlockDataRequest.js.map +1 -0
- package/src/lib/interfaces/requests/index.d.ts +1 -0
- package/src/lib/interfaces/requests/index.d.ts.map +1 -1
- package/src/lib/interfaces/websocketMessages.d.ts +30 -1
- package/src/lib/interfaces/websocketMessages.d.ts.map +1 -1
- package/src/lib/routers/api.d.ts +54 -1
- package/src/lib/routers/api.d.ts.map +1 -1
- package/src/lib/routers/api.js +77 -0
- package/src/lib/routers/api.js.map +1 -1
- package/src/lib/services/blockStore.d.ts +5 -2
- package/src/lib/services/blockStore.d.ts.map +1 -1
- package/src/lib/services/blockStore.js +4 -0
- package/src/lib/services/blockStore.js.map +1 -1
- package/src/lib/services/brightpass/auditLogger.d.ts +77 -0
- package/src/lib/services/brightpass/auditLogger.d.ts.map +1 -0
- package/src/lib/services/brightpass/auditLogger.js +184 -0
- package/src/lib/services/brightpass/auditLogger.js.map +1 -0
- package/src/lib/services/brightpass/vaultEncryption.d.ts +82 -0
- package/src/lib/services/brightpass/vaultEncryption.d.ts.map +1 -0
- package/src/lib/services/brightpass/vaultEncryption.js +144 -0
- package/src/lib/services/brightpass/vaultEncryption.js.map +1 -0
- package/src/lib/services/brightpass.d.ts +294 -0
- package/src/lib/services/brightpass.d.ts.map +1 -0
- package/src/lib/services/brightpass.js +1260 -0
- package/src/lib/services/brightpass.js.map +1 -0
- package/src/lib/services/eventNotificationSystem.d.ts +69 -3
- package/src/lib/services/eventNotificationSystem.d.ts.map +1 -1
- package/src/lib/services/eventNotificationSystem.js +200 -0
- package/src/lib/services/eventNotificationSystem.js.map +1 -1
- package/src/lib/services/expirationScheduler.d.ts +90 -0
- package/src/lib/services/expirationScheduler.d.ts.map +1 -0
- package/src/lib/services/expirationScheduler.js +131 -0
- package/src/lib/services/expirationScheduler.js.map +1 -0
- package/src/lib/services/fecUsageExample.d.ts +2 -2
- package/src/lib/services/index.d.ts +3 -0
- package/src/lib/services/index.d.ts.map +1 -1
- package/src/lib/services/index.js +3 -0
- package/src/lib/services/index.js.map +1 -1
- package/src/lib/services/messagePassingService.d.ts +95 -5
- package/src/lib/services/messagePassingService.d.ts.map +1 -1
- package/src/lib/services/messagePassingService.js +187 -28
- package/src/lib/services/messagePassingService.js.map +1 -1
- package/src/lib/services/paginationService.d.ts +18 -0
- package/src/lib/services/paginationService.d.ts.map +1 -0
- package/src/lib/services/paginationService.js +32 -0
- package/src/lib/services/paginationService.js.map +1 -0
- package/src/lib/services/presenceService.d.ts +76 -0
- package/src/lib/services/presenceService.d.ts.map +1 -0
- package/src/lib/services/presenceService.js +143 -0
- package/src/lib/services/presenceService.js.map +1 -0
- package/src/lib/services/webSocketMessageServer.d.ts +18 -23
- package/src/lib/services/webSocketMessageServer.d.ts.map +1 -1
- package/src/lib/services/webSocketMessageServer.js +30 -46
- package/src/lib/services/webSocketMessageServer.js.map +1 -1
- package/src/lib/services/webSocketPeerProvider.d.ts +49 -0
- package/src/lib/services/webSocketPeerProvider.d.ts.map +1 -0
- package/src/lib/services/webSocketPeerProvider.js +133 -0
- package/src/lib/services/webSocketPeerProvider.js.map +1 -0
- package/src/lib/services/websocketHandler.d.ts +11 -8
- package/src/lib/services/websocketHandler.d.ts.map +1 -1
- package/src/lib/services/websocketHandler.js +33 -40
- package/src/lib/services/websocketHandler.js.map +1 -1
- package/src/lib/services/wireConversationPromotion.d.ts +23 -0
- package/src/lib/services/wireConversationPromotion.d.ts.map +1 -0
- package/src/lib/services/wireConversationPromotion.js +26 -0
- package/src/lib/services/wireConversationPromotion.js.map +1 -0
- package/src/lib/stores/availabilityAwareBlockStore.d.ts +115 -10
- package/src/lib/stores/availabilityAwareBlockStore.d.ts.map +1 -1
- package/src/lib/stores/availabilityAwareBlockStore.js +267 -23
- package/src/lib/stores/availabilityAwareBlockStore.js.map +1 -1
- package/src/lib/stores/diskBlockAsyncStore.d.ts +81 -2
- package/src/lib/stores/diskBlockAsyncStore.d.ts.map +1 -1
- package/src/lib/stores/diskBlockAsyncStore.js +297 -10
- package/src/lib/stores/diskBlockAsyncStore.js.map +1 -1
- package/src/lib/stores/diskMessageMetadataStore.d.ts +2 -2
- package/src/lib/stores/diskMessageMetadataStore.d.ts.map +1 -1
- package/src/lib/stores/diskMessageMetadataStore.js +1 -1
- package/src/lib/stores/diskMessageMetadataStore.js.map +1 -1
- package/src/lib/utils/communicationValidation.d.ts +44 -0
- package/src/lib/utils/communicationValidation.d.ts.map +1 -0
- package/src/lib/utils/communicationValidation.js +291 -0
- package/src/lib/utils/communicationValidation.js.map +1 -0
- package/src/lib/utils/emailValidation.d.ts +19 -0
- package/src/lib/utils/emailValidation.d.ts.map +1 -0
- package/src/lib/utils/emailValidation.js +232 -0
- package/src/lib/utils/emailValidation.js.map +1 -0
- package/src/lib/interfaces/blockStore.d.ts +0 -7
- package/src/lib/interfaces/blockStore.d.ts.map +0 -1
- package/src/lib/interfaces/blockStore.js.map +0 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ECDSA Node Authenticator - Node.js implementation of INodeAuthenticator.
|
|
4
|
+
*
|
|
5
|
+
* Uses Node.js `crypto` module for all cryptographic operations:
|
|
6
|
+
* - Challenge: 32 random bytes via crypto.randomBytes
|
|
7
|
+
* - Sign/verify: ECDSA with secp256k1 curve (via JWK key import)
|
|
8
|
+
* - Node ID derivation: SHA-256 hash of public key (hex string)
|
|
9
|
+
*
|
|
10
|
+
* @see Requirements 9.1, 9.2, 9.3, 9.5
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.ECDSANodeAuthenticator = void 0;
|
|
14
|
+
const tslib_1 = require("tslib");
|
|
15
|
+
const crypto = tslib_1.__importStar(require("crypto"));
|
|
16
|
+
class ECDSANodeAuthenticator {
|
|
17
|
+
constructor(logger) {
|
|
18
|
+
this.logger = logger;
|
|
19
|
+
}
|
|
20
|
+
/** Generate a 32-byte random challenge nonce. */
|
|
21
|
+
createChallenge() {
|
|
22
|
+
return new Uint8Array(crypto.randomBytes(32));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Sign a challenge with the node's ECDSA private key (secp256k1).
|
|
26
|
+
* The private key must be a raw 32-byte secp256k1 private key.
|
|
27
|
+
* Returns a DER-encoded ECDSA signature.
|
|
28
|
+
*/
|
|
29
|
+
async signChallenge(challenge, privateKey) {
|
|
30
|
+
const ecdh = crypto.createECDH('secp256k1');
|
|
31
|
+
ecdh.setPrivateKey(Buffer.from(privateKey));
|
|
32
|
+
const uncompressedPub = ecdh.getPublicKey();
|
|
33
|
+
const keyObject = crypto.createPrivateKey({
|
|
34
|
+
key: this.buildPrivateJWK(privateKey, uncompressedPub),
|
|
35
|
+
format: 'jwk',
|
|
36
|
+
});
|
|
37
|
+
const signature = crypto.sign(null, Buffer.from(challenge), keyObject);
|
|
38
|
+
return new Uint8Array(signature);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Verify an ECDSA signature against a public key (secp256k1).
|
|
42
|
+
* Accepts uncompressed (65 bytes) or compressed (33 bytes) keys.
|
|
43
|
+
* Logs authentication failures when a logger is provided (Requirement 9.3).
|
|
44
|
+
*/
|
|
45
|
+
async verifySignature(challenge, signature, publicKey) {
|
|
46
|
+
try {
|
|
47
|
+
const uncompressed = this.ensureUncompressed(publicKey);
|
|
48
|
+
const keyObject = crypto.createPublicKey({
|
|
49
|
+
key: this.buildPublicJWK(uncompressed),
|
|
50
|
+
format: 'jwk',
|
|
51
|
+
});
|
|
52
|
+
const result = crypto.verify(null, Buffer.from(challenge), keyObject, Buffer.from(signature));
|
|
53
|
+
if (!result && this.logger) {
|
|
54
|
+
const nodeId = this.deriveNodeId(publicKey);
|
|
55
|
+
this.logger.logAuthFailure(nodeId, 'signature_verification');
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
if (this.logger) {
|
|
61
|
+
const nodeId = this.deriveNodeId(publicKey);
|
|
62
|
+
this.logger.logAuthFailure(nodeId, 'signature_verification');
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Derive a node ID from a public key via SHA-256 hash (hex). */
|
|
68
|
+
deriveNodeId(publicKey) {
|
|
69
|
+
return crypto
|
|
70
|
+
.createHash('sha256')
|
|
71
|
+
.update(Buffer.from(publicKey))
|
|
72
|
+
.digest('hex');
|
|
73
|
+
}
|
|
74
|
+
/** Convert compressed (33-byte) public key to uncompressed (65-byte). */
|
|
75
|
+
ensureUncompressed(publicKey) {
|
|
76
|
+
if (publicKey.length === 65 && publicKey[0] === 0x04) {
|
|
77
|
+
return Buffer.from(publicKey);
|
|
78
|
+
}
|
|
79
|
+
if (publicKey.length === 33 &&
|
|
80
|
+
(publicKey[0] === 0x02 || publicKey[0] === 0x03)) {
|
|
81
|
+
return crypto.ECDH.convertKey(Buffer.from(publicKey), 'secp256k1', undefined, undefined, 'uncompressed');
|
|
82
|
+
}
|
|
83
|
+
throw new Error(`Invalid secp256k1 public key: expected 33 or 65 bytes, got ${publicKey.length}`);
|
|
84
|
+
}
|
|
85
|
+
/** Build a JWK for a secp256k1 private key. */
|
|
86
|
+
buildPrivateJWK(rawPrivateKey, uncompressedPublicKey) {
|
|
87
|
+
const x = uncompressedPublicKey.subarray(1, 33);
|
|
88
|
+
const y = uncompressedPublicKey.subarray(33, 65);
|
|
89
|
+
return {
|
|
90
|
+
kty: 'EC',
|
|
91
|
+
crv: 'secp256k1',
|
|
92
|
+
x: x.toString('base64url'),
|
|
93
|
+
y: y.toString('base64url'),
|
|
94
|
+
d: Buffer.from(rawPrivateKey).toString('base64url'),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** Build a JWK for a secp256k1 public key (uncompressed 65-byte input). */
|
|
98
|
+
buildPublicJWK(uncompressedPublicKey) {
|
|
99
|
+
const x = uncompressedPublicKey.subarray(1, 33);
|
|
100
|
+
const y = uncompressedPublicKey.subarray(33, 65);
|
|
101
|
+
return {
|
|
102
|
+
kty: 'EC',
|
|
103
|
+
crv: 'secp256k1',
|
|
104
|
+
x: x.toString('base64url'),
|
|
105
|
+
y: y.toString('base64url'),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.ECDSANodeAuthenticator = ECDSANodeAuthenticator;
|
|
110
|
+
//# sourceMappingURL=ecdsaNodeAuthenticator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecdsaNodeAuthenticator.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/ecdsaNodeAuthenticator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './aclEnforcedAvailability';
|
|
2
|
+
export * from './aclEnforcedBlockStore';
|
|
3
|
+
export * from './ecdsaNodeAuthenticator';
|
|
4
|
+
export * from './poolAclBootstrap';
|
|
5
|
+
export * from './poolAclStore';
|
|
6
|
+
export { InsufficientQuorumError, PoolACLUpdater, type ACLUpdateProposal, } from './poolAclUpdater';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PoolACLUpdater = exports.InsufficientQuorumError = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
tslib_1.__exportStar(require("./aclEnforcedAvailability"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./aclEnforcedBlockStore"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./ecdsaNodeAuthenticator"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./poolAclBootstrap"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./poolAclStore"), exports);
|
|
10
|
+
var poolAclUpdater_1 = require("./poolAclUpdater");
|
|
11
|
+
Object.defineProperty(exports, "InsufficientQuorumError", { enumerable: true, get: function () { return poolAclUpdater_1.InsufficientQuorumError; } });
|
|
12
|
+
Object.defineProperty(exports, "PoolACLUpdater", { enumerable: true, get: function () { return poolAclUpdater_1.PoolACLUpdater; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/index.ts"],"names":[],"mappings":";;;;AAAA,oEAA0C;AAC1C,kEAAwC;AACxC,mEAAyC;AACzC,6DAAmC;AACnC,yDAA+B;AAC/B,mDAI0B;AAHxB,yHAAA,uBAAuB,OAAA;AACvB,gHAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pool ACL Bootstrap - creates the initial ACL when a new pool is created.
|
|
3
|
+
*
|
|
4
|
+
* Derives the creator's public key and node ID from their private key,
|
|
5
|
+
* creates an ACL with the creator as sole Admin, signs it, and stores it
|
|
6
|
+
* via PoolACLStore.
|
|
7
|
+
*
|
|
8
|
+
* @see Requirements 12.1, 12.2, 12.3, 12.4, 12.5, 12.6
|
|
9
|
+
*/
|
|
10
|
+
import type { IPoolACL } from '@brightchain/brightchain-lib';
|
|
11
|
+
import { ECDSANodeAuthenticator } from './ecdsaNodeAuthenticator';
|
|
12
|
+
import { PoolACLStore } from './poolAclStore';
|
|
13
|
+
export interface BootstrapPoolOptions {
|
|
14
|
+
publicRead?: boolean;
|
|
15
|
+
publicWrite?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface BootstrapPoolResult {
|
|
18
|
+
aclBlockId: string;
|
|
19
|
+
acl: IPoolACL<string>;
|
|
20
|
+
}
|
|
21
|
+
export declare class PoolACLBootstrap {
|
|
22
|
+
private readonly store;
|
|
23
|
+
private readonly authenticator;
|
|
24
|
+
constructor(store: PoolACLStore, authenticator?: ECDSANodeAuthenticator);
|
|
25
|
+
/**
|
|
26
|
+
* Bootstrap a new pool by creating and signing the initial ACL.
|
|
27
|
+
*
|
|
28
|
+
* - Derives the creator's public key and node ID from the private key
|
|
29
|
+
* - Creates an ACL with the creator as sole Admin member
|
|
30
|
+
* - Sets publicRead/publicWrite from options (default false)
|
|
31
|
+
* - Signs the ACL with the creator's key via PoolACLStore.storeACL()
|
|
32
|
+
* - Returns the block ID and the created ACL
|
|
33
|
+
*/
|
|
34
|
+
bootstrapPool(poolId: string, creatorPrivateKey: Uint8Array, options?: BootstrapPoolOptions): Promise<BootstrapPoolResult>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=poolAclBootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poolAclBootstrap.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/poolAclBootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAI7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACvB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;gBAE3C,KAAK,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,sBAAsB;IAKvE;;;;;;;;OAQG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,UAAU,EAC7B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC;CAoChC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pool ACL Bootstrap - creates the initial ACL when a new pool is created.
|
|
4
|
+
*
|
|
5
|
+
* Derives the creator's public key and node ID from their private key,
|
|
6
|
+
* creates an ACL with the creator as sole Admin, signs it, and stores it
|
|
7
|
+
* via PoolACLStore.
|
|
8
|
+
*
|
|
9
|
+
* @see Requirements 12.1, 12.2, 12.3, 12.4, 12.5, 12.6
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PoolACLBootstrap = void 0;
|
|
13
|
+
const tslib_1 = require("tslib");
|
|
14
|
+
const brightchain_lib_1 = require("@brightchain/brightchain-lib");
|
|
15
|
+
const crypto = tslib_1.__importStar(require("crypto"));
|
|
16
|
+
const ecdsaNodeAuthenticator_1 = require("./ecdsaNodeAuthenticator");
|
|
17
|
+
class PoolACLBootstrap {
|
|
18
|
+
constructor(store, authenticator) {
|
|
19
|
+
this.store = store;
|
|
20
|
+
this.authenticator = authenticator ?? new ecdsaNodeAuthenticator_1.ECDSANodeAuthenticator();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Bootstrap a new pool by creating and signing the initial ACL.
|
|
24
|
+
*
|
|
25
|
+
* - Derives the creator's public key and node ID from the private key
|
|
26
|
+
* - Creates an ACL with the creator as sole Admin member
|
|
27
|
+
* - Sets publicRead/publicWrite from options (default false)
|
|
28
|
+
* - Signs the ACL with the creator's key via PoolACLStore.storeACL()
|
|
29
|
+
* - Returns the block ID and the created ACL
|
|
30
|
+
*/
|
|
31
|
+
async bootstrapPool(poolId, creatorPrivateKey, options) {
|
|
32
|
+
// Derive creator's public key and node ID
|
|
33
|
+
const ecdh = crypto.createECDH('secp256k1');
|
|
34
|
+
ecdh.setPrivateKey(Buffer.from(creatorPrivateKey));
|
|
35
|
+
const publicKey = new Uint8Array(ecdh.getPublicKey());
|
|
36
|
+
const creatorNodeId = this.authenticator.deriveNodeId(publicKey);
|
|
37
|
+
const now = new Date();
|
|
38
|
+
// Create the initial ACL with creator as sole Admin
|
|
39
|
+
const acl = {
|
|
40
|
+
poolId,
|
|
41
|
+
owner: creatorNodeId,
|
|
42
|
+
members: [
|
|
43
|
+
{
|
|
44
|
+
nodeId: creatorNodeId,
|
|
45
|
+
permissions: [brightchain_lib_1.PoolPermission.Admin],
|
|
46
|
+
addedAt: now,
|
|
47
|
+
addedBy: creatorNodeId,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
publicRead: options?.publicRead ?? false,
|
|
51
|
+
publicWrite: options?.publicWrite ?? false,
|
|
52
|
+
approvalSignatures: [],
|
|
53
|
+
version: 1,
|
|
54
|
+
updatedAt: now,
|
|
55
|
+
};
|
|
56
|
+
// Sign and store the ACL
|
|
57
|
+
const aclBlockId = await this.store.storeACL(acl, creatorPrivateKey);
|
|
58
|
+
// Load back the stored ACL (includes the approval signature)
|
|
59
|
+
const storedAcl = await this.store.loadACL(aclBlockId);
|
|
60
|
+
return { aclBlockId, acl: storedAcl };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.PoolACLBootstrap = PoolACLBootstrap;
|
|
64
|
+
//# sourceMappingURL=poolAclBootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poolAclBootstrap.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/poolAclBootstrap.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;AAGH,kEAA8D;AAC9D,uDAAiC;AAEjC,qEAAkE;AAalE,MAAa,gBAAgB;IAI3B,YAAY,KAAmB,EAAE,aAAsC;QACrE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,IAAI,+CAAsB,EAAE,CAAC;IACrE,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,aAAa,CACjB,MAAc,EACd,iBAA6B,EAC7B,OAA8B;QAE9B,0CAA0C;QAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAC5C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAEjE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,oDAAoD;QACpD,MAAM,GAAG,GAAqB;YAC5B,MAAM;YACN,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE;gBACP;oBACE,MAAM,EAAE,aAAa;oBACrB,WAAW,EAAE,CAAC,gCAAc,CAAC,KAAK,CAAC;oBACnC,OAAO,EAAE,GAAG;oBACZ,OAAO,EAAE,aAAa;iBACvB;aACF;YACD,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,KAAK;YACxC,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,KAAK;YAC1C,kBAAkB,EAAE,EAAE;YACtB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,GAAG;SACf,CAAC;QAEF,yBAAyB;QACzB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAErE,6DAA6D;QAC7D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAEvD,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;IACxC,CAAC;CACF;AA1DD,4CA0DC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pool ACL Store - stores and retrieves ACLs as signed blocks.
|
|
3
|
+
*
|
|
4
|
+
* Each ACL is serialized to JSON (without approvalSignatures), signed with
|
|
5
|
+
* the admin's ECDSA key, and stored as a block. On retrieval, the signature
|
|
6
|
+
* is verified against the first approval signature's public key.
|
|
7
|
+
*
|
|
8
|
+
* ACL chain: each update references the previous ACL block ID via
|
|
9
|
+
* `previousAclBlockId`, forming an auditable linked list.
|
|
10
|
+
*
|
|
11
|
+
* @see Requirements 11.1, 13.3
|
|
12
|
+
*/
|
|
13
|
+
import type { IPoolACL } from '@brightchain/brightchain-lib';
|
|
14
|
+
import { ECDSANodeAuthenticator } from './ecdsaNodeAuthenticator';
|
|
15
|
+
/**
|
|
16
|
+
* The on-disk format for a signed ACL block.
|
|
17
|
+
* `aclJson` is the ACL without approvalSignatures; `signatures` carries
|
|
18
|
+
* the admin signatures as hex strings alongside their node IDs.
|
|
19
|
+
*/
|
|
20
|
+
export interface SignedACLBlock {
|
|
21
|
+
aclJson: string;
|
|
22
|
+
signatures: Array<{
|
|
23
|
+
nodeId: string;
|
|
24
|
+
signature: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Stores and retrieves Pool ACLs as signed blocks.
|
|
29
|
+
*
|
|
30
|
+
* Uses an in-memory Map for block storage (actual block store integration
|
|
31
|
+
* comes in a later task). Block IDs are SHA-256 hashes of the stored content.
|
|
32
|
+
*/
|
|
33
|
+
export declare class PoolACLStore {
|
|
34
|
+
protected readonly blocks: Map<string, Uint8Array<ArrayBufferLike>>;
|
|
35
|
+
private readonly authenticator;
|
|
36
|
+
constructor(authenticator?: ECDSANodeAuthenticator);
|
|
37
|
+
/**
|
|
38
|
+
* Serialize an ACL to JSON, sign it, and store as a block.
|
|
39
|
+
* Returns the block ID (SHA-256 hex of the stored content).
|
|
40
|
+
*/
|
|
41
|
+
storeACL(acl: IPoolACL<string>, signerPrivateKey: Uint8Array): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Load an ACL from a stored block, verifying the signature.
|
|
44
|
+
* Throws if the block doesn't exist or the signature is invalid.
|
|
45
|
+
*/
|
|
46
|
+
loadACL(blockId: string): Promise<IPoolACL<string>>;
|
|
47
|
+
/**
|
|
48
|
+
* Update an ACL: sets previousAclBlockId to the current block ID,
|
|
49
|
+
* increments version, and stores the new ACL block.
|
|
50
|
+
*/
|
|
51
|
+
updateACL(currentBlockId: string, updatedAcl: IPoolACL<string>, signerPrivateKey: Uint8Array): Promise<string>;
|
|
52
|
+
/**
|
|
53
|
+
* Store an ACL with pre-collected approval signatures (no re-signing).
|
|
54
|
+
* Used by PoolACLUpdater for quorum-based updates where multiple admins
|
|
55
|
+
* have already signed the proposal.
|
|
56
|
+
* Returns the block ID (SHA-256 hex of the stored content).
|
|
57
|
+
*/
|
|
58
|
+
storeSignedACL(acl: IPoolACL<string>): string;
|
|
59
|
+
/**
|
|
60
|
+
* Check whether a block exists in the store.
|
|
61
|
+
*/
|
|
62
|
+
hasBlock(blockId: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Serialize an ACL to JSON, stripping approvalSignatures.
|
|
65
|
+
* Dates are converted to ISO strings for deterministic serialization.
|
|
66
|
+
*/
|
|
67
|
+
private serializeACL;
|
|
68
|
+
/**
|
|
69
|
+
* Deserialize an ACL from JSON, restoring Date objects.
|
|
70
|
+
*/
|
|
71
|
+
private deserializeACL;
|
|
72
|
+
/**
|
|
73
|
+
* Compute a block ID as the SHA-256 hex digest of the content.
|
|
74
|
+
*/
|
|
75
|
+
private computeBlockId;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=poolAclStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poolAclStore.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/poolAclStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAG7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,2CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;gBAE3C,aAAa,CAAC,EAAE,sBAAsB;IAIlD;;;OAGG;IACG,QAAQ,CACZ,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,EACrB,gBAAgB,EAAE,UAAU,GAC3B,OAAO,CAAC,MAAM,CAAC;IAgClB;;;OAGG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IA0CzD;;;OAGG;IACG,SAAS,CACb,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC5B,gBAAgB,EAAE,UAAU,GAC3B,OAAO,CAAC,MAAM,CAAC;IAoBlB;;;;;OAKG;IACH,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM;IAkB7C;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIlC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAoBpB;;OAEG;IACH,OAAO,CAAC,cAAc;IA2BtB;;OAEG;IACH,OAAO,CAAC,cAAc;CAMvB"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pool ACL Store - stores and retrieves ACLs as signed blocks.
|
|
4
|
+
*
|
|
5
|
+
* Each ACL is serialized to JSON (without approvalSignatures), signed with
|
|
6
|
+
* the admin's ECDSA key, and stored as a block. On retrieval, the signature
|
|
7
|
+
* is verified against the first approval signature's public key.
|
|
8
|
+
*
|
|
9
|
+
* ACL chain: each update references the previous ACL block ID via
|
|
10
|
+
* `previousAclBlockId`, forming an auditable linked list.
|
|
11
|
+
*
|
|
12
|
+
* @see Requirements 11.1, 13.3
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.PoolACLStore = void 0;
|
|
16
|
+
const tslib_1 = require("tslib");
|
|
17
|
+
const crypto = tslib_1.__importStar(require("crypto"));
|
|
18
|
+
const ecdsaNodeAuthenticator_1 = require("./ecdsaNodeAuthenticator");
|
|
19
|
+
/**
|
|
20
|
+
* Stores and retrieves Pool ACLs as signed blocks.
|
|
21
|
+
*
|
|
22
|
+
* Uses an in-memory Map for block storage (actual block store integration
|
|
23
|
+
* comes in a later task). Block IDs are SHA-256 hashes of the stored content.
|
|
24
|
+
*/
|
|
25
|
+
class PoolACLStore {
|
|
26
|
+
constructor(authenticator) {
|
|
27
|
+
this.blocks = new Map();
|
|
28
|
+
this.authenticator = authenticator ?? new ecdsaNodeAuthenticator_1.ECDSANodeAuthenticator();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Serialize an ACL to JSON, sign it, and store as a block.
|
|
32
|
+
* Returns the block ID (SHA-256 hex of the stored content).
|
|
33
|
+
*/
|
|
34
|
+
async storeACL(acl, signerPrivateKey) {
|
|
35
|
+
const aclJson = this.serializeACL(acl);
|
|
36
|
+
const aclBytes = new TextEncoder().encode(aclJson);
|
|
37
|
+
const signature = await this.authenticator.signChallenge(aclBytes, signerPrivateKey);
|
|
38
|
+
// Derive the signer's public key and node ID
|
|
39
|
+
const ecdh = crypto.createECDH('secp256k1');
|
|
40
|
+
ecdh.setPrivateKey(Buffer.from(signerPrivateKey));
|
|
41
|
+
const publicKey = new Uint8Array(ecdh.getPublicKey());
|
|
42
|
+
const nodeId = this.authenticator.deriveNodeId(publicKey);
|
|
43
|
+
const signedBlock = {
|
|
44
|
+
aclJson,
|
|
45
|
+
signatures: [
|
|
46
|
+
{
|
|
47
|
+
nodeId,
|
|
48
|
+
signature: Buffer.from(signature).toString('hex'),
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
const blockBytes = new TextEncoder().encode(JSON.stringify(signedBlock));
|
|
53
|
+
const blockId = this.computeBlockId(blockBytes);
|
|
54
|
+
this.blocks.set(blockId, blockBytes);
|
|
55
|
+
return blockId;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Load an ACL from a stored block, verifying the signature.
|
|
59
|
+
* Throws if the block doesn't exist or the signature is invalid.
|
|
60
|
+
*/
|
|
61
|
+
async loadACL(blockId) {
|
|
62
|
+
const blockBytes = this.blocks.get(blockId);
|
|
63
|
+
if (!blockBytes) {
|
|
64
|
+
throw new Error(`ACL block not found: ${blockId}`);
|
|
65
|
+
}
|
|
66
|
+
const signedBlock = JSON.parse(new TextDecoder().decode(blockBytes));
|
|
67
|
+
// Find the signer's public key from the ACL members
|
|
68
|
+
const acl = this.deserializeACL(signedBlock.aclJson);
|
|
69
|
+
if (signedBlock.signatures.length === 0) {
|
|
70
|
+
throw new Error('ACL block has no signatures');
|
|
71
|
+
}
|
|
72
|
+
// Verify the first signature against the signer's public key from ACL members
|
|
73
|
+
const firstSig = signedBlock.signatures[0];
|
|
74
|
+
const signerMember = acl.members.find((m) => typeof m.nodeId === 'string' && m.nodeId === firstSig.nodeId);
|
|
75
|
+
if (!signerMember) {
|
|
76
|
+
throw new Error(`Signer ${firstSig.nodeId} is not a member of the ACL`);
|
|
77
|
+
}
|
|
78
|
+
// We cannot verify without the public key stored somewhere accessible.
|
|
79
|
+
// For now, the signature is stored and the ACL is returned with it
|
|
80
|
+
// attached in approvalSignatures. Full verification requires a public
|
|
81
|
+
// key registry (future task). The signed block format preserves the
|
|
82
|
+
// signature for downstream verification.
|
|
83
|
+
// Reconstruct approvalSignatures from the signed block
|
|
84
|
+
acl.approvalSignatures = signedBlock.signatures.map((s) => ({
|
|
85
|
+
nodeId: s.nodeId,
|
|
86
|
+
signature: new Uint8Array(Buffer.from(s.signature, 'hex')),
|
|
87
|
+
}));
|
|
88
|
+
return acl;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Update an ACL: sets previousAclBlockId to the current block ID,
|
|
92
|
+
* increments version, and stores the new ACL block.
|
|
93
|
+
*/
|
|
94
|
+
async updateACL(currentBlockId, updatedAcl, signerPrivateKey) {
|
|
95
|
+
// Verify the current block exists
|
|
96
|
+
if (!this.blocks.has(currentBlockId)) {
|
|
97
|
+
throw new Error(`Current ACL block not found: ${currentBlockId}`);
|
|
98
|
+
}
|
|
99
|
+
// Load the current ACL to get its version
|
|
100
|
+
const currentAcl = await this.loadACL(currentBlockId);
|
|
101
|
+
// Set chain reference and increment version
|
|
102
|
+
const chainedAcl = {
|
|
103
|
+
...updatedAcl,
|
|
104
|
+
previousAclBlockId: currentBlockId,
|
|
105
|
+
version: currentAcl.version + 1,
|
|
106
|
+
updatedAt: new Date(),
|
|
107
|
+
};
|
|
108
|
+
return this.storeACL(chainedAcl, signerPrivateKey);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Store an ACL with pre-collected approval signatures (no re-signing).
|
|
112
|
+
* Used by PoolACLUpdater for quorum-based updates where multiple admins
|
|
113
|
+
* have already signed the proposal.
|
|
114
|
+
* Returns the block ID (SHA-256 hex of the stored content).
|
|
115
|
+
*/
|
|
116
|
+
storeSignedACL(acl) {
|
|
117
|
+
const aclJson = this.serializeACL(acl);
|
|
118
|
+
const signedBlock = {
|
|
119
|
+
aclJson,
|
|
120
|
+
signatures: acl.approvalSignatures.map((s) => ({
|
|
121
|
+
nodeId: s.nodeId,
|
|
122
|
+
signature: Buffer.from(s.signature).toString('hex'),
|
|
123
|
+
})),
|
|
124
|
+
};
|
|
125
|
+
const blockBytes = new TextEncoder().encode(JSON.stringify(signedBlock));
|
|
126
|
+
const blockId = this.computeBlockId(blockBytes);
|
|
127
|
+
this.blocks.set(blockId, blockBytes);
|
|
128
|
+
return blockId;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check whether a block exists in the store.
|
|
132
|
+
*/
|
|
133
|
+
hasBlock(blockId) {
|
|
134
|
+
return this.blocks.has(blockId);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Serialize an ACL to JSON, stripping approvalSignatures.
|
|
138
|
+
* Dates are converted to ISO strings for deterministic serialization.
|
|
139
|
+
*/
|
|
140
|
+
serializeACL(acl) {
|
|
141
|
+
const { approvalSignatures: _, ...aclWithoutSigs } = acl;
|
|
142
|
+
// Convert Dates to ISO strings for stable JSON
|
|
143
|
+
const serializable = {
|
|
144
|
+
...aclWithoutSigs,
|
|
145
|
+
updatedAt: acl.updatedAt instanceof Date
|
|
146
|
+
? acl.updatedAt.toISOString()
|
|
147
|
+
: acl.updatedAt,
|
|
148
|
+
members: acl.members.map((m) => ({
|
|
149
|
+
...m,
|
|
150
|
+
addedAt: m.addedAt instanceof Date ? m.addedAt.toISOString() : m.addedAt,
|
|
151
|
+
})),
|
|
152
|
+
};
|
|
153
|
+
return JSON.stringify(serializable);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Deserialize an ACL from JSON, restoring Date objects.
|
|
157
|
+
*/
|
|
158
|
+
deserializeACL(json) {
|
|
159
|
+
const raw = JSON.parse(json);
|
|
160
|
+
const members = raw['members'].map((m) => ({
|
|
161
|
+
nodeId: m['nodeId'],
|
|
162
|
+
permissions: m['permissions'],
|
|
163
|
+
addedAt: new Date(m['addedAt']),
|
|
164
|
+
addedBy: m['addedBy'],
|
|
165
|
+
}));
|
|
166
|
+
return {
|
|
167
|
+
poolId: raw['poolId'],
|
|
168
|
+
owner: raw['owner'],
|
|
169
|
+
members,
|
|
170
|
+
publicRead: raw['publicRead'],
|
|
171
|
+
publicWrite: raw['publicWrite'],
|
|
172
|
+
previousAclBlockId: raw['previousAclBlockId'],
|
|
173
|
+
approvalSignatures: [],
|
|
174
|
+
version: raw['version'],
|
|
175
|
+
updatedAt: new Date(raw['updatedAt']),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Compute a block ID as the SHA-256 hex digest of the content.
|
|
180
|
+
*/
|
|
181
|
+
computeBlockId(content) {
|
|
182
|
+
return crypto
|
|
183
|
+
.createHash('sha256')
|
|
184
|
+
.update(Buffer.from(content))
|
|
185
|
+
.digest('hex');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.PoolACLStore = PoolACLStore;
|
|
189
|
+
//# sourceMappingURL=poolAclStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poolAclStore.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/poolAclStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pool ACL Updater - quorum-based ACL update workflow.
|
|
3
|
+
*
|
|
4
|
+
* Provides a propose → collect signatures → apply workflow for ACL changes.
|
|
5
|
+
* Uses `hasQuorum()` from brightchain-lib to verify majority approval.
|
|
6
|
+
*
|
|
7
|
+
* @see Requirements 13.1, 13.2, 13.5, 13.6
|
|
8
|
+
*/
|
|
9
|
+
import type { IPoolACL } from '@brightchain/brightchain-lib';
|
|
10
|
+
import { ECDSANodeAuthenticator } from './ecdsaNodeAuthenticator';
|
|
11
|
+
import { PoolACLStore } from './poolAclStore';
|
|
12
|
+
/**
|
|
13
|
+
* Error thrown when an ACL update would remove the last Admin.
|
|
14
|
+
* @see Requirement 13.6
|
|
15
|
+
*/
|
|
16
|
+
export declare class LastAdminError extends Error {
|
|
17
|
+
constructor();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown when an ACL update does not have sufficient signatures.
|
|
21
|
+
* @see Requirement 13.5
|
|
22
|
+
*/
|
|
23
|
+
export declare class InsufficientQuorumError extends Error {
|
|
24
|
+
readonly required: number;
|
|
25
|
+
readonly actual: number;
|
|
26
|
+
constructor(required: number, actual: number);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A proposal for an ACL update that collects admin signatures.
|
|
30
|
+
*/
|
|
31
|
+
export interface ACLUpdateProposal {
|
|
32
|
+
currentBlockId: string;
|
|
33
|
+
proposedAcl: IPoolACL<string>;
|
|
34
|
+
signatures: Array<{
|
|
35
|
+
nodeId: string;
|
|
36
|
+
signature: Uint8Array;
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
export declare class PoolACLUpdater {
|
|
40
|
+
private readonly store;
|
|
41
|
+
private readonly authenticator;
|
|
42
|
+
constructor(store: PoolACLStore, authenticator?: ECDSANodeAuthenticator);
|
|
43
|
+
/**
|
|
44
|
+
* Propose an ACL update. Validates that at least one Admin remains.
|
|
45
|
+
* Returns a proposal object that can collect signatures before applying.
|
|
46
|
+
*
|
|
47
|
+
* @see Requirements 13.1, 13.6
|
|
48
|
+
*/
|
|
49
|
+
proposeUpdate(currentBlockId: string, proposedAcl: IPoolACL<string>): Promise<ACLUpdateProposal>;
|
|
50
|
+
/**
|
|
51
|
+
* Sign a proposal with an admin's private key and add the signature.
|
|
52
|
+
* Derives the node ID from the private key and signs the serialized
|
|
53
|
+
* proposed ACL.
|
|
54
|
+
*
|
|
55
|
+
* @see Requirement 13.1
|
|
56
|
+
*/
|
|
57
|
+
addSignature(proposal: ACLUpdateProposal, signerPrivateKey: Uint8Array): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Apply a proposed ACL update if quorum is met.
|
|
60
|
+
* Attaches collected signatures to the ACL, checks quorum via
|
|
61
|
+
* `hasQuorum()`, and stores the updated ACL via `PoolACLStore.updateACL()`.
|
|
62
|
+
*
|
|
63
|
+
* @returns The new ACL block ID
|
|
64
|
+
* @throws InsufficientQuorumError if quorum is not met
|
|
65
|
+
* @see Requirements 13.1, 13.2, 13.5
|
|
66
|
+
*/
|
|
67
|
+
applyUpdate(proposal: ACLUpdateProposal): Promise<string>;
|
|
68
|
+
/**
|
|
69
|
+
* Validate that the proposed ACL has at least one Admin member.
|
|
70
|
+
* @throws LastAdminError if no Admin members remain
|
|
71
|
+
* @see Requirement 13.6
|
|
72
|
+
*/
|
|
73
|
+
validateMinAdmin(acl: IPoolACL<string>): void;
|
|
74
|
+
/**
|
|
75
|
+
* Serialize an ACL for signing (deterministic JSON without signatures).
|
|
76
|
+
*/
|
|
77
|
+
private serializeForSigning;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=poolAclUpdater.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poolAclUpdater.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/auth/poolAclUpdater.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAI7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK;;CAKxC;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEnB,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAQ7C;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9B,UAAU,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CAC9D;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;gBAE3C,KAAK,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,sBAAsB;IAKvE;;;;;OAKG;IACG,aAAa,CACjB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC5B,OAAO,CAAC,iBAAiB,CAAC;IAU7B;;;;;;OAMG;IACG,YAAY,CAChB,QAAQ,EAAE,iBAAiB,EAC3B,gBAAgB,EAAE,UAAU,GAC3B,OAAO,CAAC,IAAI,CAAC;IAkBhB;;;;;;;;OAQG;IACG,WAAW,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAoC/D;;;;OAIG;IACH,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI;IAS7C;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAgB5B"}
|