shogun-core 6.2.3 → 6.3.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/dist/browser/defaultVendors-node_modules_noble_curves_esm_ed448_js.shogun-core.js +93 -341
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_ed448_js.shogun-core.js.map +1 -1
- package/dist/browser/shogun-core.js +138850 -146638
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/{core.js → src/core.js} +167 -107
- package/dist/src/crypto/asymmetric.js +168 -0
- package/dist/src/crypto/double-ratchet.js +908 -0
- package/dist/src/crypto/file-encryption.js +352 -0
- package/dist/src/crypto/hashing.js +160 -0
- package/dist/src/crypto/index.js +18 -0
- package/dist/{crypto → src/crypto}/mls-codec.js +24 -34
- package/dist/src/crypto/mls.js +734 -0
- package/dist/src/crypto/pgp.js +619 -0
- package/dist/{crypto → src/crypto}/random-generation.js +125 -103
- package/dist/src/crypto/sframe.js +466 -0
- package/dist/src/crypto/signal-protocol.js +943 -0
- package/dist/src/crypto/symmetric.js +165 -0
- package/dist/src/crypto/utils.js +220 -0
- package/dist/src/examples/auth-test.js +535 -0
- package/dist/src/examples/crypto-identity-example.js +294 -0
- package/dist/src/examples/crypto-working-test.js +149 -0
- package/dist/src/examples/double-ratchet-test.js +240 -0
- package/dist/src/examples/mls-3-member-test.js +183 -0
- package/dist/src/examples/mls-multi-member.js +439 -0
- package/dist/src/examples/mls-sframe-test.js +491 -0
- package/dist/src/examples/mls-simple-test.js +122 -0
- package/dist/src/examples/pgp-example.js +354 -0
- package/dist/src/examples/random-generation-test.js +191 -0
- package/dist/src/examples/shogun-core-example.js +204 -0
- package/dist/src/examples/signal-protocol-test.js +82 -0
- package/dist/src/examples/zkproof-credentials-example.js +357 -0
- package/dist/src/examples/zkproof-example.js +357 -0
- package/dist/src/gundb/crypto.js +420 -0
- package/dist/src/gundb/db.js +728 -0
- package/dist/src/gundb/derive.js +327 -0
- package/dist/src/gundb/errors.js +115 -0
- package/dist/src/gundb/gun-es.js +8 -0
- package/dist/src/gundb/index.js +5 -0
- package/dist/{gundb → src/gundb}/rxjs.js +147 -111
- package/dist/{gundb → src/gundb}/types.js +1 -2
- package/dist/src/index.js +19 -0
- package/dist/src/interfaces/events.js +57 -0
- package/dist/{interfaces → src/interfaces}/shogun.js +4 -7
- package/dist/src/managers/AuthManager.js +301 -0
- package/dist/src/managers/CoreInitializer.js +304 -0
- package/dist/src/managers/CryptoIdentityManager.js +230 -0
- package/dist/{managers → src/managers}/EventManager.js +19 -21
- package/dist/{managers → src/managers}/PluginManager.js +123 -89
- package/dist/src/plugins/base.js +90 -0
- package/dist/src/plugins/index.js +17 -0
- package/dist/src/plugins/nostr/index.js +4 -0
- package/dist/src/plugins/nostr/nostrConnector.js +539 -0
- package/dist/src/plugins/nostr/nostrConnectorPlugin.js +663 -0
- package/dist/src/plugins/nostr/nostrSigner.js +414 -0
- package/dist/src/plugins/smartwallet/index.js +2 -0
- package/dist/src/plugins/smartwallet/smartWalletPlugin.js +824 -0
- package/dist/src/plugins/web3/index.js +4 -0
- package/dist/src/plugins/web3/types.js +1 -0
- package/dist/src/plugins/web3/web3Connector.js +738 -0
- package/dist/src/plugins/web3/web3ConnectorPlugin.js +639 -0
- package/dist/src/plugins/web3/web3Signer.js +432 -0
- package/dist/src/plugins/webauthn/index.js +3 -0
- package/dist/{plugins → src/plugins}/webauthn/types.js +2 -5
- package/dist/src/plugins/webauthn/webauthn.js +647 -0
- package/dist/src/plugins/webauthn/webauthnPlugin.js +689 -0
- package/dist/src/plugins/webauthn/webauthnSigner.js +419 -0
- package/dist/{plugins → src/plugins}/zkproof/index.js +3 -10
- package/dist/src/plugins/zkproof/types.js +1 -0
- package/dist/src/plugins/zkproof/zkCredentials.js +287 -0
- package/dist/src/plugins/zkproof/zkProofConnector.js +267 -0
- package/dist/src/plugins/zkproof/zkProofPlugin.js +405 -0
- package/dist/src/storage/storage.js +189 -0
- package/dist/src/utils/errorHandler.js +339 -0
- package/dist/{utils → src/utils}/eventEmitter.js +26 -26
- package/dist/{utils → src/utils}/seedPhrase.js +23 -32
- package/dist/{utils → src/utils}/validation.js +14 -21
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/{crypto → src/crypto}/double-ratchet.d.ts +1 -1
- package/dist/types/{crypto → src/crypto}/signal-protocol.d.ts +25 -0
- package/dist/types/{crypto → src/crypto}/types.d.ts +3 -1
- package/dist/types/src/examples/crypto-working-test.d.ts +1 -0
- package/dist/types/src/examples/double-ratchet-test.d.ts +1 -0
- package/dist/types/src/examples/mls-sframe-test.d.ts +1 -0
- package/dist/types/src/examples/random-generation-test.d.ts +1 -0
- package/dist/types/src/examples/signal-protocol-test.d.ts +1 -0
- package/dist/types/{gundb → src/gundb}/db.d.ts +14 -1
- package/dist/types/src/gundb/gun-es.d.ts +8 -0
- package/dist/types/src/gundb/min.d.ts +3 -0
- package/dist/types/{index.d.ts → src/index.d.ts} +1 -0
- package/package.json +14 -11
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_abstract_curve_js-node_modules_noble_curves_esm_-1ce4ed.shogun-core.js +0 -1651
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_abstract_curve_js-node_modules_noble_curves_esm_-1ce4ed.shogun-core.js.map +0 -1
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_nist_js.shogun-core.js +0 -1608
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_nist_js.shogun-core.js.map +0 -1
- package/dist/crypto/asymmetric.js +0 -99
- package/dist/crypto/double-ratchet.js +0 -370
- package/dist/crypto/file-encryption.js +0 -213
- package/dist/crypto/hashing.js +0 -87
- package/dist/crypto/index.js +0 -34
- package/dist/crypto/mls.js +0 -569
- package/dist/crypto/pgp.js +0 -390
- package/dist/crypto/sframe.js +0 -352
- package/dist/crypto/signal-protocol.js +0 -456
- package/dist/crypto/symmetric.js +0 -91
- package/dist/crypto/types.js +0 -2
- package/dist/crypto/utils.js +0 -140
- package/dist/examples/auth-test.js +0 -453
- package/dist/examples/crypto-identity-example.js +0 -196
- package/dist/examples/crypto-working-test.js +0 -83
- package/dist/examples/double-ratchet-test.js +0 -155
- package/dist/examples/mls-3-member-test.js +0 -97
- package/dist/examples/mls-multi-member.js +0 -153
- package/dist/examples/mls-sframe-test.js +0 -307
- package/dist/examples/mls-simple-test.js +0 -58
- package/dist/examples/pgp-example.js +0 -200
- package/dist/examples/random-generation-test.js +0 -151
- package/dist/examples/shogun-core-example.js +0 -150
- package/dist/examples/signal-protocol-test.js +0 -38
- package/dist/examples/zkproof-credentials-example.js +0 -217
- package/dist/examples/zkproof-example.js +0 -242
- package/dist/gundb/crypto.js +0 -306
- package/dist/gundb/db.js +0 -485
- package/dist/gundb/derive.js +0 -232
- package/dist/gundb/errors.js +0 -76
- package/dist/gundb/gun-es.js +0 -12
- package/dist/gundb/index.js +0 -21
- package/dist/gundb/min.js +0 -10
- package/dist/index.esm.js +0 -22
- package/dist/index.js +0 -47
- package/dist/interfaces/common.js +0 -2
- package/dist/interfaces/events.js +0 -40
- package/dist/interfaces/plugin.js +0 -2
- package/dist/managers/AuthManager.js +0 -226
- package/dist/managers/CoreInitializer.js +0 -250
- package/dist/managers/CryptoIdentityManager.js +0 -138
- package/dist/plugins/base.js +0 -50
- package/dist/plugins/index.js +0 -32
- package/dist/plugins/nostr/index.js +0 -20
- package/dist/plugins/nostr/nostrConnector.js +0 -419
- package/dist/plugins/nostr/nostrConnectorPlugin.js +0 -453
- package/dist/plugins/nostr/nostrSigner.js +0 -319
- package/dist/plugins/nostr/types.js +0 -2
- package/dist/plugins/smartwallet/index.js +0 -18
- package/dist/plugins/smartwallet/smartWalletPlugin.js +0 -511
- package/dist/plugins/smartwallet/types.js +0 -2
- package/dist/plugins/web3/index.js +0 -20
- package/dist/plugins/web3/types.js +0 -2
- package/dist/plugins/web3/web3Connector.js +0 -533
- package/dist/plugins/web3/web3ConnectorPlugin.js +0 -455
- package/dist/plugins/web3/web3Signer.js +0 -314
- package/dist/plugins/webauthn/index.js +0 -19
- package/dist/plugins/webauthn/webauthn.js +0 -496
- package/dist/plugins/webauthn/webauthnPlugin.js +0 -490
- package/dist/plugins/webauthn/webauthnSigner.js +0 -310
- package/dist/plugins/zkproof/types.js +0 -2
- package/dist/plugins/zkproof/zkCredentials.js +0 -216
- package/dist/plugins/zkproof/zkProofConnector.js +0 -198
- package/dist/plugins/zkproof/zkProofPlugin.js +0 -272
- package/dist/storage/storage.js +0 -145
- package/dist/types/gundb/gun-es.d.ts +0 -8
- package/dist/utils/errorHandler.js +0 -246
- /package/dist/{types/examples/crypto-working-test.d.ts → src/crypto/types.js} +0 -0
- /package/dist/{types/gundb/min.d.ts → src/gundb/min.js} +0 -0
- /package/dist/{types/examples/double-ratchet-test.d.ts → src/interfaces/common.js} +0 -0
- /package/dist/{types/examples/mls-sframe-test.d.ts → src/interfaces/plugin.js} +0 -0
- /package/dist/{types/examples/random-generation-test.d.ts → src/plugins/nostr/types.js} +0 -0
- /package/dist/{types/examples/signal-protocol-test.d.ts → src/plugins/smartwallet/types.js} +0 -0
- /package/dist/types/{core.d.ts → src/core.d.ts} +0 -0
- /package/dist/types/{crypto → src/crypto}/asymmetric.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/file-encryption.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/hashing.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/index.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/mls-codec.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/mls.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/pgp.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/random-generation.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/sframe.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/symmetric.d.ts +0 -0
- /package/dist/types/{crypto → src/crypto}/utils.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/auth-test.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/crypto-identity-example.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/mls-3-member-test.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/mls-multi-member.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/mls-simple-test.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/pgp-example.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/shogun-core-example.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/zkproof-credentials-example.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/zkproof-example.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/crypto.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/derive.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/errors.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/index.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/rxjs.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/types.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/common.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/events.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/plugin.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/shogun.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/AuthManager.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/CoreInitializer.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/CryptoIdentityManager.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/EventManager.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/PluginManager.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/base.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/nostrConnector.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/nostrConnectorPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/nostrSigner.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/smartwallet/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/smartwallet/smartWalletPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/smartwallet/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/web3Connector.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/web3ConnectorPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/web3Signer.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/webauthn.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/webauthnPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/webauthnSigner.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/zkproof/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/zkproof/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/zkproof/zkCredentials.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/zkproof/zkProofConnector.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/zkproof/zkProofPlugin.d.ts +0 -0
- /package/dist/types/{storage → src/storage}/storage.d.ts +0 -0
- /package/dist/types/{utils → src/utils}/errorHandler.d.ts +0 -0
- /package/dist/types/{utils → src/utils}/eventEmitter.d.ts +0 -0
- /package/dist/types/{utils → src/utils}/seedPhrase.d.ts +0 -0
- /package/dist/types/{utils → src/utils}/validation.d.ts +0 -0
|
@@ -0,0 +1,734 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MLS (Message Layer Security) Manager
|
|
3
|
+
* RFC 9420 implementation using ts-mls library
|
|
4
|
+
* Provides end-to-end encrypted group messaging with forward secrecy
|
|
5
|
+
*/
|
|
6
|
+
var __assign = (this && this.__assign) || function () {
|
|
7
|
+
__assign = Object.assign || function(t) {
|
|
8
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
9
|
+
s = arguments[i];
|
|
10
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
11
|
+
t[p] = s[p];
|
|
12
|
+
}
|
|
13
|
+
return t;
|
|
14
|
+
};
|
|
15
|
+
return __assign.apply(this, arguments);
|
|
16
|
+
};
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
28
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
import { createApplicationMessage, createCommit, createGroup, joinGroup, processPrivateMessage, processPublicMessage, getCiphersuiteFromName, generateKeyPackage, encodeMlsMessage, decodeMlsMessage, defaultCapabilities, defaultLifetime, emptyPskIndex, nobleCryptoProvider, } from "ts-mls";
|
|
54
|
+
// Helper to strip trailing null nodes per RFC 9420
|
|
55
|
+
function stripTrailingNulls(tree) {
|
|
56
|
+
var lastNonNull = tree.length - 1;
|
|
57
|
+
while (lastNonNull >= 0 && tree[lastNonNull] === null) {
|
|
58
|
+
lastNonNull--;
|
|
59
|
+
}
|
|
60
|
+
return tree.slice(0, lastNonNull + 1);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* MLSManager wraps the ts-mls functional API with a class-based interface
|
|
64
|
+
* for easier state management in applications
|
|
65
|
+
*/
|
|
66
|
+
var MLSManager = /** @class */ (function () {
|
|
67
|
+
function MLSManager(userId) {
|
|
68
|
+
this.cipherSuite = null;
|
|
69
|
+
this.initialized = false;
|
|
70
|
+
this.groups = new Map();
|
|
71
|
+
this.keyPackage = null;
|
|
72
|
+
this.userId = userId;
|
|
73
|
+
this.credential = {
|
|
74
|
+
credentialType: "basic",
|
|
75
|
+
identity: new TextEncoder().encode(userId),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Initialize the MLS client with a ciphersuite
|
|
80
|
+
*/
|
|
81
|
+
MLSManager.prototype.initialize = function () {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
83
|
+
var cipherSuiteName, cs, _a, error_1;
|
|
84
|
+
return __generator(this, function (_b) {
|
|
85
|
+
switch (_b.label) {
|
|
86
|
+
case 0:
|
|
87
|
+
if (this.initialized) {
|
|
88
|
+
console.warn("MLS Manager already initialized");
|
|
89
|
+
return [2 /*return*/];
|
|
90
|
+
}
|
|
91
|
+
_b.label = 1;
|
|
92
|
+
case 1:
|
|
93
|
+
_b.trys.push([1, 4, , 5]);
|
|
94
|
+
console.log("\uD83D\uDD10 [MLS] Initializing for user: ".concat(this.userId));
|
|
95
|
+
cipherSuiteName = "MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519";
|
|
96
|
+
cs = getCiphersuiteFromName(cipherSuiteName);
|
|
97
|
+
_a = this;
|
|
98
|
+
return [4 /*yield*/, nobleCryptoProvider.getCiphersuiteImpl(cs)];
|
|
99
|
+
case 2:
|
|
100
|
+
_a.cipherSuite = _b.sent();
|
|
101
|
+
console.log("\u2705 [MLS] Using ciphersuite: ".concat(cipherSuiteName));
|
|
102
|
+
// Mark as initialized before generating key package
|
|
103
|
+
this.initialized = true;
|
|
104
|
+
// Generate initial key package for this user
|
|
105
|
+
return [4 /*yield*/, this.generateKeyPackage()];
|
|
106
|
+
case 3:
|
|
107
|
+
// Generate initial key package for this user
|
|
108
|
+
_b.sent();
|
|
109
|
+
console.log("✅ [MLS] Initialized successfully");
|
|
110
|
+
return [3 /*break*/, 5];
|
|
111
|
+
case 4:
|
|
112
|
+
error_1 = _b.sent();
|
|
113
|
+
console.error("❌ [MLS] Failed to initialize:", error_1);
|
|
114
|
+
throw new Error("MLS initialization failed: ".concat(error_1 instanceof Error ? error_1.message : String(error_1)));
|
|
115
|
+
case 5: return [2 /*return*/];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Generate a new key package for joining groups
|
|
122
|
+
*/
|
|
123
|
+
MLSManager.prototype.generateKeyPackage = function () {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
125
|
+
var keyPackageResult, error_2;
|
|
126
|
+
return __generator(this, function (_a) {
|
|
127
|
+
switch (_a.label) {
|
|
128
|
+
case 0:
|
|
129
|
+
this.ensureInitialized();
|
|
130
|
+
_a.label = 1;
|
|
131
|
+
case 1:
|
|
132
|
+
_a.trys.push([1, 3, , 4]);
|
|
133
|
+
console.log("🔑 [MLS] Generating key package");
|
|
134
|
+
return [4 /*yield*/, generateKeyPackage(this.credential, defaultCapabilities(), defaultLifetime, [], this.cipherSuite)];
|
|
135
|
+
case 2:
|
|
136
|
+
keyPackageResult = _a.sent();
|
|
137
|
+
this.keyPackage = __assign(__assign({}, keyPackageResult), { userId: this.userId });
|
|
138
|
+
console.log("✅ [MLS] Key package generated");
|
|
139
|
+
return [2 /*return*/, this.keyPackage];
|
|
140
|
+
case 3:
|
|
141
|
+
error_2 = _a.sent();
|
|
142
|
+
console.error("❌ [MLS] Failed to generate key package:", error_2);
|
|
143
|
+
throw new Error("Key package generation failed: ".concat(error_2 instanceof Error ? error_2.message : String(error_2)));
|
|
144
|
+
case 4: return [2 /*return*/];
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Get the current key package
|
|
151
|
+
*/
|
|
152
|
+
MLSManager.prototype.getKeyPackage = function () {
|
|
153
|
+
return this.keyPackage;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Create a new MLS group
|
|
157
|
+
*/
|
|
158
|
+
MLSManager.prototype.createGroup = function (groupId) {
|
|
159
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
160
|
+
var groupIdBytes, groupState, groupInfo, error_3;
|
|
161
|
+
return __generator(this, function (_a) {
|
|
162
|
+
switch (_a.label) {
|
|
163
|
+
case 0:
|
|
164
|
+
this.ensureInitialized();
|
|
165
|
+
_a.label = 1;
|
|
166
|
+
case 1:
|
|
167
|
+
_a.trys.push([1, 3, , 4]);
|
|
168
|
+
console.log("\uD83D\uDCDD [MLS] Creating group: ".concat(groupId));
|
|
169
|
+
if (!this.keyPackage) {
|
|
170
|
+
throw new Error("No key package available. Call generateKeyPackage() first.");
|
|
171
|
+
}
|
|
172
|
+
groupIdBytes = new TextEncoder().encode(groupId);
|
|
173
|
+
return [4 /*yield*/, createGroup(groupIdBytes, this.keyPackage.publicPackage, this.keyPackage.privatePackage, [], this.cipherSuite)];
|
|
174
|
+
case 2:
|
|
175
|
+
groupState = _a.sent();
|
|
176
|
+
this.groups.set(groupId, groupState);
|
|
177
|
+
groupInfo = {
|
|
178
|
+
groupId: groupIdBytes,
|
|
179
|
+
members: [this.userId],
|
|
180
|
+
epoch: groupState.groupContext.epoch,
|
|
181
|
+
};
|
|
182
|
+
console.log("\u2705 [MLS] Group created: ".concat(groupId, ", epoch: ").concat(groupState.groupContext.epoch));
|
|
183
|
+
return [2 /*return*/, groupInfo];
|
|
184
|
+
case 3:
|
|
185
|
+
error_3 = _a.sent();
|
|
186
|
+
console.error("❌ [MLS] Failed to create group:", error_3);
|
|
187
|
+
throw new Error("Group creation failed: ".concat(error_3 instanceof Error ? error_3.message : String(error_3)));
|
|
188
|
+
case 4: return [2 /*return*/];
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Add members to an existing group
|
|
195
|
+
*/
|
|
196
|
+
MLSManager.prototype.addMembers = function (groupId, keyPackages) {
|
|
197
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
198
|
+
var groupState, addProposals, commitResult, ratchetTreeArray, strippedTree, error_4;
|
|
199
|
+
var _a;
|
|
200
|
+
return __generator(this, function (_b) {
|
|
201
|
+
switch (_b.label) {
|
|
202
|
+
case 0:
|
|
203
|
+
this.ensureInitialized();
|
|
204
|
+
_b.label = 1;
|
|
205
|
+
case 1:
|
|
206
|
+
_b.trys.push([1, 3, , 4]);
|
|
207
|
+
console.log("\u2795 [MLS] Adding ".concat(keyPackages.length, " member(s) to group: ").concat(groupId));
|
|
208
|
+
groupState = this.groups.get(groupId);
|
|
209
|
+
if (!groupState) {
|
|
210
|
+
throw new Error("Group ".concat(groupId, " not found"));
|
|
211
|
+
}
|
|
212
|
+
addProposals = keyPackages.map(function (kp) { return ({
|
|
213
|
+
proposalType: "add",
|
|
214
|
+
add: {
|
|
215
|
+
keyPackage: kp.publicPackage,
|
|
216
|
+
},
|
|
217
|
+
}); });
|
|
218
|
+
return [4 /*yield*/, createCommit({ state: groupState, cipherSuite: this.cipherSuite }, { extraProposals: addProposals })];
|
|
219
|
+
case 2:
|
|
220
|
+
commitResult = _b.sent();
|
|
221
|
+
// Update group state
|
|
222
|
+
this.groups.set(groupId, commitResult.newState);
|
|
223
|
+
if (!commitResult.welcome) {
|
|
224
|
+
throw new Error("No welcome message generated");
|
|
225
|
+
}
|
|
226
|
+
console.log("\u2705 [MLS] Members added, new epoch: ".concat(commitResult.newState.groupContext.epoch));
|
|
227
|
+
// Debug: Log the commit structure
|
|
228
|
+
console.group("🔍 [MLS Debug] Commit Structure");
|
|
229
|
+
console.log("commitResult keys:", Object.keys(commitResult));
|
|
230
|
+
console.log("commit:", commitResult.commit);
|
|
231
|
+
if (((_a = commitResult.commit) === null || _a === void 0 ? void 0 : _a.wireformat) === "mls_private_message") {
|
|
232
|
+
console.log("commit.privateMessage:", commitResult.commit.privateMessage);
|
|
233
|
+
}
|
|
234
|
+
console.groupEnd();
|
|
235
|
+
ratchetTreeArray = Array.from(commitResult.newState.ratchetTree);
|
|
236
|
+
strippedTree = stripTrailingNulls(ratchetTreeArray);
|
|
237
|
+
console.log("\uD83D\uDD0D [MLS] Ratchet tree stripped: ".concat(ratchetTreeArray.length, " -> ").concat(strippedTree.length, " nodes"));
|
|
238
|
+
return [2 /*return*/, {
|
|
239
|
+
welcome: commitResult.welcome,
|
|
240
|
+
ratchetTree: strippedTree,
|
|
241
|
+
commit: commitResult.commit,
|
|
242
|
+
}];
|
|
243
|
+
case 3:
|
|
244
|
+
error_4 = _b.sent();
|
|
245
|
+
console.error("❌ [MLS] Failed to add members:", error_4);
|
|
246
|
+
throw new Error("Adding members failed: ".concat(error_4 instanceof Error ? error_4.message : String(error_4)));
|
|
247
|
+
case 4: return [2 /*return*/];
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Process a Welcome message to join an MLS group
|
|
254
|
+
*
|
|
255
|
+
* RFC 9420 Compliance:
|
|
256
|
+
* - Interior null nodes represent blank parent nodes (unmerged positions)
|
|
257
|
+
* - These nulls are REQUIRED for proper binary tree structure
|
|
258
|
+
* - Trailing nulls are stripped by sender (per RFC 9420 requirement)
|
|
259
|
+
* - ratchetTree parameter is optional; ts-mls can extract from Welcome extension
|
|
260
|
+
*
|
|
261
|
+
* @param welcome - The Welcome message from group creator
|
|
262
|
+
* @param ratchetTree - Optional ratchet tree (normally provided out-of-band)
|
|
263
|
+
*/
|
|
264
|
+
MLSManager.prototype.processWelcome = function (welcome, ratchetTree) {
|
|
265
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
266
|
+
var nullCount, groupState, groupId, members, groupInfo, error_5;
|
|
267
|
+
return __generator(this, function (_a) {
|
|
268
|
+
switch (_a.label) {
|
|
269
|
+
case 0:
|
|
270
|
+
this.ensureInitialized();
|
|
271
|
+
_a.label = 1;
|
|
272
|
+
case 1:
|
|
273
|
+
_a.trys.push([1, 3, , 4]);
|
|
274
|
+
console.log("📩 [MLS] Processing welcome message");
|
|
275
|
+
if (!this.keyPackage) {
|
|
276
|
+
throw new Error("No key package available");
|
|
277
|
+
}
|
|
278
|
+
// RFC 9420: Interior null nodes are valid (represent blank parent nodes)
|
|
279
|
+
// Trailing nulls are stripped by sender per RFC requirement
|
|
280
|
+
// Simply pass the tree as-is to ts-mls joinGroup()
|
|
281
|
+
if (ratchetTree && Array.isArray(ratchetTree)) {
|
|
282
|
+
nullCount = ratchetTree.filter(function (n) { return n === null; }).length;
|
|
283
|
+
console.log("\uD83D\uDD0D [MLS] Ratchet tree received: ".concat(ratchetTree.length, " nodes (").concat(nullCount, " interior nulls)"));
|
|
284
|
+
// DEBUG: Log structure of each node
|
|
285
|
+
console.group("🔍 [MLS Debug] Ratchet Tree Structure");
|
|
286
|
+
ratchetTree.forEach(function (node, i) {
|
|
287
|
+
if (node === null) {
|
|
288
|
+
console.log(" Node ".concat(i, ": NULL"));
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
console.log(" Node ".concat(i, ":"), {
|
|
292
|
+
type: typeof node,
|
|
293
|
+
isObject: typeof node === "object" && node !== null,
|
|
294
|
+
hasNodeType: typeof node === "object" && node !== null && "nodeType" in node,
|
|
295
|
+
nodeType: node === null || node === void 0 ? void 0 : node.nodeType,
|
|
296
|
+
keys: node && typeof node === "object"
|
|
297
|
+
? Object.keys(node).slice(0, 5)
|
|
298
|
+
: "n/a",
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
console.groupEnd();
|
|
303
|
+
}
|
|
304
|
+
return [4 /*yield*/, joinGroup(welcome, this.keyPackage.publicPackage, this.keyPackage.privatePackage, emptyPskIndex, this.cipherSuite, ratchetTree)];
|
|
305
|
+
case 2:
|
|
306
|
+
groupState = _a.sent();
|
|
307
|
+
groupId = new TextDecoder().decode(groupState.groupContext.groupId);
|
|
308
|
+
this.groups.set(groupId, groupState);
|
|
309
|
+
members = this.extractMembersFromState(groupState);
|
|
310
|
+
groupInfo = {
|
|
311
|
+
groupId: groupState.groupContext.groupId,
|
|
312
|
+
members: members,
|
|
313
|
+
epoch: groupState.groupContext.epoch,
|
|
314
|
+
};
|
|
315
|
+
console.log("\u2705 [MLS] Welcome processed, joined group: ".concat(groupId));
|
|
316
|
+
return [2 /*return*/, groupInfo];
|
|
317
|
+
case 3:
|
|
318
|
+
error_5 = _a.sent();
|
|
319
|
+
console.error("❌ [MLS] Failed to process welcome:", error_5);
|
|
320
|
+
throw new Error("Welcome processing failed: ".concat(error_5 instanceof Error ? error_5.message : String(error_5)));
|
|
321
|
+
case 4: return [2 /*return*/];
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* Encrypt a message for a group
|
|
328
|
+
*/
|
|
329
|
+
MLSManager.prototype.encryptMessage = function (groupId, plaintext) {
|
|
330
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
331
|
+
var groupState, plaintextBytes, result, encoded, envelope, error_6;
|
|
332
|
+
return __generator(this, function (_a) {
|
|
333
|
+
switch (_a.label) {
|
|
334
|
+
case 0:
|
|
335
|
+
this.ensureInitialized();
|
|
336
|
+
_a.label = 1;
|
|
337
|
+
case 1:
|
|
338
|
+
_a.trys.push([1, 3, , 4]);
|
|
339
|
+
console.log("\uD83D\uDD12 [MLS] Encrypting message for group: ".concat(groupId));
|
|
340
|
+
groupState = this.groups.get(groupId);
|
|
341
|
+
if (!groupState) {
|
|
342
|
+
throw new Error("Group ".concat(groupId, " not found"));
|
|
343
|
+
}
|
|
344
|
+
plaintextBytes = new TextEncoder().encode(plaintext);
|
|
345
|
+
return [4 /*yield*/, createApplicationMessage(groupState, plaintextBytes, this.cipherSuite)];
|
|
346
|
+
case 2:
|
|
347
|
+
result = _a.sent();
|
|
348
|
+
// Update group state (for key ratcheting)
|
|
349
|
+
this.groups.set(groupId, result.newState);
|
|
350
|
+
encoded = encodeMlsMessage({
|
|
351
|
+
privateMessage: result.privateMessage,
|
|
352
|
+
wireformat: "mls_private_message",
|
|
353
|
+
version: "mls10",
|
|
354
|
+
});
|
|
355
|
+
envelope = {
|
|
356
|
+
groupId: new TextEncoder().encode(groupId),
|
|
357
|
+
ciphertext: encoded,
|
|
358
|
+
timestamp: Date.now(),
|
|
359
|
+
};
|
|
360
|
+
console.log("✅ [MLS] Message encrypted");
|
|
361
|
+
return [2 /*return*/, envelope];
|
|
362
|
+
case 3:
|
|
363
|
+
error_6 = _a.sent();
|
|
364
|
+
console.error("❌ [MLS] Failed to encrypt message:", error_6);
|
|
365
|
+
throw new Error("Message encryption failed: ".concat(error_6 instanceof Error ? error_6.message : String(error_6)));
|
|
366
|
+
case 4: return [2 /*return*/];
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Decrypt a message from a group
|
|
373
|
+
*/
|
|
374
|
+
MLSManager.prototype.decryptMessage = function (envelope) {
|
|
375
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
376
|
+
var groupId, groupState, decoded, decodedMessage, result, plaintext, error_7;
|
|
377
|
+
return __generator(this, function (_a) {
|
|
378
|
+
switch (_a.label) {
|
|
379
|
+
case 0:
|
|
380
|
+
this.ensureInitialized();
|
|
381
|
+
_a.label = 1;
|
|
382
|
+
case 1:
|
|
383
|
+
_a.trys.push([1, 3, , 4]);
|
|
384
|
+
groupId = new TextDecoder().decode(envelope.groupId);
|
|
385
|
+
console.log("\uD83D\uDD13 [MLS] Decrypting message for group: ".concat(groupId));
|
|
386
|
+
groupState = this.groups.get(groupId);
|
|
387
|
+
if (!groupState) {
|
|
388
|
+
throw new Error("Group ".concat(groupId, " not found"));
|
|
389
|
+
}
|
|
390
|
+
decoded = decodeMlsMessage(envelope.ciphertext, 0);
|
|
391
|
+
if (!decoded || decoded.length === 0) {
|
|
392
|
+
// Changed from 0n to 0 to fix type error
|
|
393
|
+
throw new Error("Failed to decode message");
|
|
394
|
+
}
|
|
395
|
+
decodedMessage = decoded[0];
|
|
396
|
+
if (decodedMessage.wireformat !== "mls_private_message") {
|
|
397
|
+
throw new Error("Expected private message");
|
|
398
|
+
}
|
|
399
|
+
return [4 /*yield*/, processPrivateMessage(groupState, decodedMessage.privateMessage, emptyPskIndex, this.cipherSuite)];
|
|
400
|
+
case 2:
|
|
401
|
+
result = _a.sent();
|
|
402
|
+
// Update group state
|
|
403
|
+
this.groups.set(groupId, result.newState);
|
|
404
|
+
if (result.kind !== "applicationMessage") {
|
|
405
|
+
throw new Error("Expected application message");
|
|
406
|
+
}
|
|
407
|
+
plaintext = new TextDecoder().decode(result.message);
|
|
408
|
+
console.log("✅ [MLS] Message decrypted");
|
|
409
|
+
return [2 /*return*/, plaintext];
|
|
410
|
+
case 3:
|
|
411
|
+
error_7 = _a.sent();
|
|
412
|
+
console.error("❌ [MLS] Failed to decrypt message:", error_7);
|
|
413
|
+
throw new Error("Decryption failed: ".concat(error_7 instanceof Error ? error_7.message : String(error_7)));
|
|
414
|
+
case 4: return [2 /*return*/];
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
/**
|
|
420
|
+
* Update the group keys (key rotation)
|
|
421
|
+
*/
|
|
422
|
+
MLSManager.prototype.updateKey = function (groupId) {
|
|
423
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
424
|
+
var groupState, commitResult, error_8;
|
|
425
|
+
return __generator(this, function (_a) {
|
|
426
|
+
switch (_a.label) {
|
|
427
|
+
case 0:
|
|
428
|
+
this.ensureInitialized();
|
|
429
|
+
_a.label = 1;
|
|
430
|
+
case 1:
|
|
431
|
+
_a.trys.push([1, 3, , 4]);
|
|
432
|
+
console.log("\uD83D\uDD04 [MLS] Performing key rotation for group: ".concat(groupId));
|
|
433
|
+
groupState = this.groups.get(groupId);
|
|
434
|
+
if (!groupState) {
|
|
435
|
+
throw new Error("Group ".concat(groupId, " not found"));
|
|
436
|
+
}
|
|
437
|
+
return [4 /*yield*/, createCommit({ state: groupState, cipherSuite: this.cipherSuite }, {})];
|
|
438
|
+
case 2:
|
|
439
|
+
commitResult = _a.sent();
|
|
440
|
+
// Update group state
|
|
441
|
+
this.groups.set(groupId, commitResult.newState);
|
|
442
|
+
console.log("\u2705 [MLS] Key rotation successful, new epoch: ".concat(commitResult.newState.groupContext.epoch));
|
|
443
|
+
// Return the raw commit object for other members to process
|
|
444
|
+
return [2 /*return*/, commitResult.commit];
|
|
445
|
+
case 3:
|
|
446
|
+
error_8 = _a.sent();
|
|
447
|
+
console.error("❌ [MLS] Failed to update key:", error_8);
|
|
448
|
+
throw new Error("Key update failed: ".concat(error_8 instanceof Error ? error_8.message : String(error_8)));
|
|
449
|
+
case 4: return [2 /*return*/];
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
};
|
|
454
|
+
/**
|
|
455
|
+
* Process a commit message (key rotation, member changes)
|
|
456
|
+
*
|
|
457
|
+
* RFC 9420 Section 12.1.8:
|
|
458
|
+
* - Update commits (key rotation) → PrivateMessage
|
|
459
|
+
* - Add/Remove commits → PublicMessage (for existing group members)
|
|
460
|
+
*
|
|
461
|
+
* This implementation handles both types based on wireformat.
|
|
462
|
+
*/
|
|
463
|
+
MLSManager.prototype.processCommit = function (groupId, commit) {
|
|
464
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
465
|
+
var groupState, result, publicMessage, privateMessage, error_9;
|
|
466
|
+
var _a;
|
|
467
|
+
return __generator(this, function (_b) {
|
|
468
|
+
switch (_b.label) {
|
|
469
|
+
case 0:
|
|
470
|
+
this.ensureInitialized();
|
|
471
|
+
_b.label = 1;
|
|
472
|
+
case 1:
|
|
473
|
+
_b.trys.push([1, 7, , 8]);
|
|
474
|
+
console.log("\u2699\uFE0F [MLS] Processing commit for group: ".concat(groupId));
|
|
475
|
+
console.log("\uD83D\uDD0D [MLS Debug] Commit wireformat: ".concat(commit.wireformat));
|
|
476
|
+
// DETAILED DEBUG LOGGING
|
|
477
|
+
console.group("🔍 [MLS Debug] Full Commit Structure");
|
|
478
|
+
console.log("commit keys:", Object.keys(commit));
|
|
479
|
+
console.log("commit.wireformat:", commit.wireformat);
|
|
480
|
+
console.log("commit.publicMessage:", commit.publicMessage);
|
|
481
|
+
console.log("commit.privateMessage:", commit.privateMessage);
|
|
482
|
+
// Log proposals if present
|
|
483
|
+
if ((_a = commit.publicMessage) === null || _a === void 0 ? void 0 : _a.content) {
|
|
484
|
+
console.log("publicMessage.content:", commit.publicMessage.content);
|
|
485
|
+
console.log("publicMessage.content.proposals:", commit.publicMessage.content.proposals);
|
|
486
|
+
if (commit.publicMessage.content.proposals) {
|
|
487
|
+
commit.publicMessage.content.proposals.forEach(function (prop, i) {
|
|
488
|
+
console.log(" Proposal ".concat(i, ":"), {
|
|
489
|
+
proposalType: prop.proposalType,
|
|
490
|
+
keys: Object.keys(prop),
|
|
491
|
+
full: prop,
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
console.groupEnd();
|
|
497
|
+
groupState = this.groups.get(groupId);
|
|
498
|
+
if (!groupState) {
|
|
499
|
+
throw new Error("Group ".concat(groupId, " not found"));
|
|
500
|
+
}
|
|
501
|
+
result = void 0;
|
|
502
|
+
if (!(commit.wireformat === "mls_public_message")) return [3 /*break*/, 3];
|
|
503
|
+
// Public messages (add/remove member commits)
|
|
504
|
+
console.log("🔍 [MLS Debug] Processing as PUBLIC message (add/remove)...");
|
|
505
|
+
publicMessage = commit.publicMessage || commit;
|
|
506
|
+
return [4 /*yield*/, processPublicMessage(groupState, publicMessage, emptyPskIndex, this.cipherSuite)];
|
|
507
|
+
case 2:
|
|
508
|
+
result = _b.sent();
|
|
509
|
+
return [3 /*break*/, 6];
|
|
510
|
+
case 3:
|
|
511
|
+
if (!(commit.wireformat === "mls_private_message")) return [3 /*break*/, 5];
|
|
512
|
+
// Private messages (update/key rotation commits)
|
|
513
|
+
console.log("🔍 [MLS Debug] Processing as PRIVATE message (update)...");
|
|
514
|
+
privateMessage = commit.privateMessage || commit;
|
|
515
|
+
return [4 /*yield*/, processPrivateMessage(groupState, privateMessage, emptyPskIndex, this.cipherSuite)];
|
|
516
|
+
case 4:
|
|
517
|
+
result = _b.sent();
|
|
518
|
+
return [3 /*break*/, 6];
|
|
519
|
+
case 5: throw new Error("Unknown commit wireformat: ".concat(commit.wireformat));
|
|
520
|
+
case 6:
|
|
521
|
+
// Update group state
|
|
522
|
+
this.groups.set(groupId, result.newState);
|
|
523
|
+
console.log("\u2705 [MLS] Commit processed, epoch: ".concat(result.newState.groupContext.epoch));
|
|
524
|
+
return [3 /*break*/, 8];
|
|
525
|
+
case 7:
|
|
526
|
+
error_9 = _b.sent();
|
|
527
|
+
console.error("❌ [MLS] Failed to process commit:", error_9);
|
|
528
|
+
console.error("❌ [MLS Debug] Error details:", error_9 instanceof Error ? error_9.stack : String(error_9));
|
|
529
|
+
console.error("❌ [MLS Debug] Error message:", error_9 instanceof Error ? error_9.message : String(error_9));
|
|
530
|
+
throw new Error("Commit processing failed: ".concat(error_9 instanceof Error ? error_9.message : String(error_9)));
|
|
531
|
+
case 8: return [2 /*return*/];
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
});
|
|
535
|
+
};
|
|
536
|
+
/**
|
|
537
|
+
* Remove members from a group
|
|
538
|
+
*/
|
|
539
|
+
MLSManager.prototype.removeMembers = function (groupId, memberIndices) {
|
|
540
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
541
|
+
var groupState, removeProposals, commitResult, encodedCommit, error_10;
|
|
542
|
+
return __generator(this, function (_a) {
|
|
543
|
+
switch (_a.label) {
|
|
544
|
+
case 0:
|
|
545
|
+
this.ensureInitialized();
|
|
546
|
+
_a.label = 1;
|
|
547
|
+
case 1:
|
|
548
|
+
_a.trys.push([1, 3, , 4]);
|
|
549
|
+
console.log("\u2796 [MLS] Removing ".concat(memberIndices.length, " member(s) from group: ").concat(groupId));
|
|
550
|
+
groupState = this.groups.get(groupId);
|
|
551
|
+
if (!groupState) {
|
|
552
|
+
throw new Error("Group ".concat(groupId, " not found"));
|
|
553
|
+
}
|
|
554
|
+
removeProposals = memberIndices.map(function (index) { return ({
|
|
555
|
+
proposalType: "remove",
|
|
556
|
+
remove: {
|
|
557
|
+
removed: index, // Changed from BigInt(index) to number
|
|
558
|
+
},
|
|
559
|
+
}); });
|
|
560
|
+
return [4 /*yield*/, createCommit({ state: groupState, cipherSuite: this.cipherSuite }, { extraProposals: removeProposals })];
|
|
561
|
+
case 2:
|
|
562
|
+
commitResult = _a.sent();
|
|
563
|
+
// Update group state
|
|
564
|
+
this.groups.set(groupId, commitResult.newState);
|
|
565
|
+
encodedCommit = void 0;
|
|
566
|
+
if (commitResult.commit &&
|
|
567
|
+
commitResult.commit.wireformat === "mls_public_message") {
|
|
568
|
+
encodedCommit = encodeMlsMessage({
|
|
569
|
+
publicMessage: commitResult.commit
|
|
570
|
+
.publicMessage,
|
|
571
|
+
wireformat: "mls_public_message",
|
|
572
|
+
version: "mls10",
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
// Fallback or error handling if not a public message
|
|
577
|
+
// For now, we'll assume it should be public for remove operation.
|
|
578
|
+
throw new Error("Commit result does not contain a public message for encoding.");
|
|
579
|
+
}
|
|
580
|
+
console.log("✅ [MLS] Members removed");
|
|
581
|
+
return [2 /*return*/, encodedCommit];
|
|
582
|
+
case 3:
|
|
583
|
+
error_10 = _a.sent();
|
|
584
|
+
console.error("❌ [MLS] Failed to remove members:", error_10);
|
|
585
|
+
throw new Error("Member removal failed: ".concat(error_10 instanceof Error ? error_10.message : String(error_10)));
|
|
586
|
+
case 4: return [2 /*return*/];
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* Get list of groups
|
|
593
|
+
*/
|
|
594
|
+
MLSManager.prototype.getGroups = function () {
|
|
595
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
596
|
+
var groupIds;
|
|
597
|
+
return __generator(this, function (_a) {
|
|
598
|
+
this.ensureInitialized();
|
|
599
|
+
try {
|
|
600
|
+
groupIds = Array.from(this.groups.keys()).map(function (id) {
|
|
601
|
+
return new TextEncoder().encode(id);
|
|
602
|
+
});
|
|
603
|
+
return [2 /*return*/, groupIds];
|
|
604
|
+
}
|
|
605
|
+
catch (error) {
|
|
606
|
+
console.error("❌ [MLS] Failed to get groups:", error);
|
|
607
|
+
throw new Error("Getting groups failed: ".concat(error instanceof Error ? error.message : String(error)));
|
|
608
|
+
}
|
|
609
|
+
return [2 /*return*/];
|
|
610
|
+
});
|
|
611
|
+
});
|
|
612
|
+
};
|
|
613
|
+
/**
|
|
614
|
+
* Export group state for persistence
|
|
615
|
+
*/
|
|
616
|
+
MLSManager.prototype.exportGroupState = function (groupId) {
|
|
617
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
618
|
+
var groupState, exportData;
|
|
619
|
+
return __generator(this, function (_a) {
|
|
620
|
+
this.ensureInitialized();
|
|
621
|
+
try {
|
|
622
|
+
console.log("\uD83D\uDCBE [MLS] Exporting state for group: ".concat(groupId));
|
|
623
|
+
groupState = this.groups.get(groupId);
|
|
624
|
+
if (!groupState) {
|
|
625
|
+
throw new Error("Group ".concat(groupId, " not found"));
|
|
626
|
+
}
|
|
627
|
+
exportData = {
|
|
628
|
+
groupId: groupId,
|
|
629
|
+
epoch: groupState.groupContext.epoch.toString(),
|
|
630
|
+
exported: Date.now(),
|
|
631
|
+
// Add other serializable fields as needed
|
|
632
|
+
};
|
|
633
|
+
console.log("✅ [MLS] Group state exported");
|
|
634
|
+
return [2 /*return*/, exportData];
|
|
635
|
+
}
|
|
636
|
+
catch (error) {
|
|
637
|
+
console.error("❌ [MLS] Failed to export group state:", error);
|
|
638
|
+
throw new Error("Group state export failed: ".concat(error instanceof Error ? error.message : String(error)));
|
|
639
|
+
}
|
|
640
|
+
return [2 /*return*/];
|
|
641
|
+
});
|
|
642
|
+
});
|
|
643
|
+
};
|
|
644
|
+
/**
|
|
645
|
+
* Get user ID
|
|
646
|
+
*/
|
|
647
|
+
MLSManager.prototype.getUserId = function () {
|
|
648
|
+
return this.userId;
|
|
649
|
+
};
|
|
650
|
+
/**
|
|
651
|
+
* Get group information
|
|
652
|
+
*/
|
|
653
|
+
MLSManager.prototype.getGroupKeyInfo = function (groupId) {
|
|
654
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
655
|
+
var groupState, members;
|
|
656
|
+
return __generator(this, function (_a) {
|
|
657
|
+
groupState = this.groups.get(groupId);
|
|
658
|
+
if (!groupState) {
|
|
659
|
+
return [2 /*return*/, null];
|
|
660
|
+
}
|
|
661
|
+
members = this.extractMembersFromState(groupState);
|
|
662
|
+
return [2 /*return*/, {
|
|
663
|
+
groupId: groupId,
|
|
664
|
+
epoch: groupState.groupContext.epoch.toString(),
|
|
665
|
+
members: members,
|
|
666
|
+
cipherSuite: "MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519",
|
|
667
|
+
treeHash: this.bytesToHex(groupState.groupContext.treeHash).substring(0, 16),
|
|
668
|
+
}];
|
|
669
|
+
});
|
|
670
|
+
});
|
|
671
|
+
};
|
|
672
|
+
/**
|
|
673
|
+
* Clean up resources
|
|
674
|
+
*/
|
|
675
|
+
MLSManager.prototype.destroy = function () {
|
|
676
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
677
|
+
return __generator(this, function (_a) {
|
|
678
|
+
this.groups.clear();
|
|
679
|
+
this.keyPackage = null;
|
|
680
|
+
this.initialized = false;
|
|
681
|
+
console.log("✅ [MLS] Manager destroyed");
|
|
682
|
+
return [2 /*return*/];
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
};
|
|
686
|
+
/**
|
|
687
|
+
* Extract member identities from group state
|
|
688
|
+
*/
|
|
689
|
+
MLSManager.prototype.extractMembersFromState = function (state) {
|
|
690
|
+
var members = [];
|
|
691
|
+
try {
|
|
692
|
+
// Iterate through ratchet tree to find leaf nodes
|
|
693
|
+
for (var i = 0; i < state.ratchetTree.length; i++) {
|
|
694
|
+
var node = state.ratchetTree[i];
|
|
695
|
+
if (node &&
|
|
696
|
+
node.nodeType === "leaf" &&
|
|
697
|
+
node.leaf.credential) {
|
|
698
|
+
var credential = node.leaf.credential;
|
|
699
|
+
if (credential.credentialType === "basic" && credential.identity) {
|
|
700
|
+
var identity = new TextDecoder().decode(credential.identity);
|
|
701
|
+
members.push(identity);
|
|
702
|
+
}
|
|
703
|
+
else {
|
|
704
|
+
console.warn("Skipping credential without basic identity:", credential);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
catch (error) {
|
|
710
|
+
console.warn("Could not extract members:", error);
|
|
711
|
+
members.push(this.userId); // At least include self
|
|
712
|
+
}
|
|
713
|
+
return members;
|
|
714
|
+
};
|
|
715
|
+
/**
|
|
716
|
+
* Convert bytes to hex string
|
|
717
|
+
*/
|
|
718
|
+
MLSManager.prototype.bytesToHex = function (bytes) {
|
|
719
|
+
return Array.from(bytes)
|
|
720
|
+
.map(function (b) { return b.toString(16).padStart(2, "0"); })
|
|
721
|
+
.join("");
|
|
722
|
+
};
|
|
723
|
+
/**
|
|
724
|
+
* Ensure the manager is initialized
|
|
725
|
+
*/
|
|
726
|
+
MLSManager.prototype.ensureInitialized = function () {
|
|
727
|
+
if (!this.initialized) {
|
|
728
|
+
throw new Error("MLS Manager not initialized. Call initialize() first.");
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
return MLSManager;
|
|
732
|
+
}());
|
|
733
|
+
export { MLSManager };
|
|
734
|
+
export default MLSManager;
|