shogun-core 3.2.1 β 3.2.3
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.
|
@@ -98546,15 +98546,12 @@ class MessengerCLI {
|
|
|
98546
98546
|
this.app = new SHIP_01_1.SHIP_01({
|
|
98547
98547
|
gunOptions: {
|
|
98548
98548
|
peers: [
|
|
98549
|
+
"https://peer.wallie.io/gun",
|
|
98549
98550
|
"https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun",
|
|
98550
98551
|
"https://relay.shogun-eco.xyz/gun",
|
|
98551
|
-
"https://peer.wallie.io/gun",
|
|
98552
98552
|
],
|
|
98553
|
-
radisk:
|
|
98553
|
+
radisk: true,
|
|
98554
98554
|
localStorage: false,
|
|
98555
|
-
multicast: false, // Disabilita multicast per evitare blocchi
|
|
98556
|
-
wire: false,
|
|
98557
|
-
axe: false,
|
|
98558
98555
|
},
|
|
98559
98556
|
});
|
|
98560
98557
|
// Don't initialize readline in browser environment
|
|
@@ -98859,13 +98856,13 @@ class MessengerCLI {
|
|
|
98859
98856
|
if (answer.trim() === "CONFERMA") {
|
|
98860
98857
|
console.log(c("yellow", "ποΈ Cancellazione messaggi in corso..."));
|
|
98861
98858
|
// Ottieni tutti i messaggi
|
|
98862
|
-
this.app["shogun"].db.gun.get(
|
|
98859
|
+
this.app["shogun"].db.gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).once((allMessages) => {
|
|
98863
98860
|
if (allMessages && typeof allMessages === 'object') {
|
|
98864
98861
|
let count = 0;
|
|
98865
98862
|
// Cancella ogni messaggio
|
|
98866
98863
|
for (const [messageId, data] of Object.entries(allMessages)) {
|
|
98867
98864
|
if (typeof data === "object" && data !== null && messageId !== '_') {
|
|
98868
|
-
this.app["shogun"].db.gun.get(
|
|
98865
|
+
this.app["shogun"].db.gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).get(messageId).put(null);
|
|
98869
98866
|
count++;
|
|
98870
98867
|
}
|
|
98871
98868
|
}
|
|
@@ -99193,7 +99190,7 @@ class SHIP_01 {
|
|
|
99193
99190
|
if (!signupResult.success) {
|
|
99194
99191
|
return {
|
|
99195
99192
|
success: false,
|
|
99196
|
-
error: signupResult.error || "Signup failed"
|
|
99193
|
+
error: signupResult.error || "Signup failed",
|
|
99197
99194
|
};
|
|
99198
99195
|
}
|
|
99199
99196
|
console.log("β
Utente registrato");
|
|
@@ -99209,13 +99206,13 @@ class SHIP_01 {
|
|
|
99209
99206
|
return {
|
|
99210
99207
|
success: true,
|
|
99211
99208
|
userPub: signupResult.pub,
|
|
99212
|
-
derivedAddress
|
|
99209
|
+
derivedAddress,
|
|
99213
99210
|
};
|
|
99214
99211
|
}
|
|
99215
99212
|
catch (error) {
|
|
99216
99213
|
return {
|
|
99217
99214
|
success: false,
|
|
99218
|
-
error: error.message
|
|
99215
|
+
error: error.message,
|
|
99219
99216
|
};
|
|
99220
99217
|
}
|
|
99221
99218
|
}
|
|
@@ -99229,7 +99226,7 @@ class SHIP_01 {
|
|
|
99229
99226
|
if (!loginResult.success) {
|
|
99230
99227
|
return {
|
|
99231
99228
|
success: false,
|
|
99232
|
-
error: loginResult.error || "Login failed"
|
|
99229
|
+
error: loginResult.error || "Login failed",
|
|
99233
99230
|
};
|
|
99234
99231
|
}
|
|
99235
99232
|
console.log("β
Login effettuato");
|
|
@@ -99245,13 +99242,13 @@ class SHIP_01 {
|
|
|
99245
99242
|
return {
|
|
99246
99243
|
success: true,
|
|
99247
99244
|
userPub: loginResult.userPub,
|
|
99248
|
-
derivedAddress
|
|
99245
|
+
derivedAddress,
|
|
99249
99246
|
};
|
|
99250
99247
|
}
|
|
99251
99248
|
catch (error) {
|
|
99252
99249
|
return {
|
|
99253
99250
|
success: false,
|
|
99254
|
-
error: error.message
|
|
99251
|
+
error: error.message,
|
|
99255
99252
|
};
|
|
99256
99253
|
}
|
|
99257
99254
|
}
|
|
@@ -99296,7 +99293,7 @@ class SHIP_01 {
|
|
|
99296
99293
|
return {
|
|
99297
99294
|
success: true,
|
|
99298
99295
|
userPub: authResult.userPub,
|
|
99299
|
-
derivedAddress
|
|
99296
|
+
derivedAddress,
|
|
99300
99297
|
};
|
|
99301
99298
|
}
|
|
99302
99299
|
catch (error) {
|
|
@@ -99340,12 +99337,15 @@ class SHIP_01 {
|
|
|
99340
99337
|
// Salva chiave pubblica sul nodo globale usando il userPub come chiave
|
|
99341
99338
|
// Questo permette ad altri di trovarla facilmente
|
|
99342
99339
|
const userPub = currentUser.is.pub;
|
|
99343
|
-
await this.shogun.db.gun
|
|
99340
|
+
await this.shogun.db.gun
|
|
99341
|
+
.get(userPub)
|
|
99342
|
+
.put({
|
|
99344
99343
|
pub: currentUser.is.pub,
|
|
99345
99344
|
epub: currentUser.is.epub,
|
|
99346
99345
|
algorithm: "ECDSA",
|
|
99347
|
-
timestamp: Date.now().toString()
|
|
99348
|
-
})
|
|
99346
|
+
timestamp: Date.now().toString(),
|
|
99347
|
+
})
|
|
99348
|
+
.then();
|
|
99349
99349
|
console.log(`π Chiave pubblica pubblicata su GunDB`);
|
|
99350
99350
|
return { success: true };
|
|
99351
99351
|
}
|
|
@@ -99374,7 +99374,7 @@ class SHIP_01 {
|
|
|
99374
99374
|
if (!recipientKey) {
|
|
99375
99375
|
return {
|
|
99376
99376
|
success: false,
|
|
99377
|
-
error: `Recipient ${recipientUsername} has not published their public key
|
|
99377
|
+
error: `Recipient ${recipientUsername} has not published their public key`,
|
|
99378
99378
|
};
|
|
99379
99379
|
}
|
|
99380
99380
|
// 2. Ottieni il SEA pair completo (include chiavi private)
|
|
@@ -99395,20 +99395,24 @@ class SHIP_01 {
|
|
|
99395
99395
|
to: recipientUsername,
|
|
99396
99396
|
content: encryptedMessage, // Contenuto crittografato!
|
|
99397
99397
|
timestamp: Date.now().toString(),
|
|
99398
|
-
messageId: messageId
|
|
99398
|
+
messageId: messageId,
|
|
99399
99399
|
};
|
|
99400
99400
|
// Salva sul nodo globale 'messages' per permettere il listener
|
|
99401
|
-
await this.shogun.db.gun
|
|
99401
|
+
await this.shogun.db.gun
|
|
99402
|
+
.get(SHIP_01.NODES.MESSAGES)
|
|
99403
|
+
.get(messageId)
|
|
99404
|
+
.put(messageData)
|
|
99405
|
+
.then();
|
|
99402
99406
|
console.log(`β
Messaggio salvato: ${messageId}`);
|
|
99403
99407
|
return {
|
|
99404
99408
|
success: true,
|
|
99405
|
-
messageId: messageId
|
|
99409
|
+
messageId: messageId,
|
|
99406
99410
|
};
|
|
99407
99411
|
}
|
|
99408
99412
|
catch (error) {
|
|
99409
99413
|
return {
|
|
99410
99414
|
success: false,
|
|
99411
|
-
error: error.message
|
|
99415
|
+
error: error.message,
|
|
99412
99416
|
};
|
|
99413
99417
|
}
|
|
99414
99418
|
}
|
|
@@ -99429,7 +99433,7 @@ class SHIP_01 {
|
|
|
99429
99433
|
if (publicKeyData && publicKeyData.epub && publicKeyData.pub) {
|
|
99430
99434
|
return {
|
|
99431
99435
|
pub: publicKeyData.pub,
|
|
99432
|
-
epub: publicKeyData.epub
|
|
99436
|
+
epub: publicKeyData.epub,
|
|
99433
99437
|
};
|
|
99434
99438
|
}
|
|
99435
99439
|
return null;
|
|
@@ -99462,11 +99466,15 @@ class SHIP_01 {
|
|
|
99462
99466
|
const receivedMessages = new Set();
|
|
99463
99467
|
// Ascolta messaggi in tempo reale su GunDB
|
|
99464
99468
|
this.shogun.db.gun
|
|
99465
|
-
.get(
|
|
99469
|
+
.get(SHIP_01.NODES.MESSAGES)
|
|
99466
99470
|
.map()
|
|
99467
99471
|
.on(async (data, key) => {
|
|
99468
99472
|
// Filtra solo i messaggi destinati a questo utente (per username)
|
|
99469
|
-
if (data &&
|
|
99473
|
+
if (data &&
|
|
99474
|
+
data.to === username &&
|
|
99475
|
+
data.from &&
|
|
99476
|
+
data.content &&
|
|
99477
|
+
data.messageId) {
|
|
99470
99478
|
// Evita duplicati (GunDB puΓ² emettere piΓΉ volte)
|
|
99471
99479
|
if (receivedMessages.has(data.messageId)) {
|
|
99472
99480
|
return;
|
|
@@ -99478,7 +99486,7 @@ class SHIP_01 {
|
|
|
99478
99486
|
onMessage({
|
|
99479
99487
|
from: data.from,
|
|
99480
99488
|
content: decryptedContent,
|
|
99481
|
-
timestamp: parseInt(data.timestamp)
|
|
99489
|
+
timestamp: parseInt(data.timestamp),
|
|
99482
99490
|
});
|
|
99483
99491
|
}
|
|
99484
99492
|
catch (error) {
|
|
@@ -99518,7 +99526,7 @@ class SHIP_01 {
|
|
|
99518
99526
|
if (publicKeyData && publicKeyData.epub && publicKeyData.pub) {
|
|
99519
99527
|
return {
|
|
99520
99528
|
pub: publicKeyData.pub,
|
|
99521
|
-
epub: publicKeyData.epub
|
|
99529
|
+
epub: publicKeyData.epub,
|
|
99522
99530
|
};
|
|
99523
99531
|
}
|
|
99524
99532
|
return null;
|
|
@@ -99547,38 +99555,29 @@ class SHIP_01 {
|
|
|
99547
99555
|
const userPub = currentUser.is.pub;
|
|
99548
99556
|
const username = currentUser.is.alias;
|
|
99549
99557
|
const allMessages = [];
|
|
99550
|
-
console.log(`[SHIP-01] Getting history between ${username} (${userPub.substring(0, 20)}...) and ${withUsername}`);
|
|
99551
99558
|
// Ottieni il userPub dell'altro utente
|
|
99552
99559
|
const otherUserData = await this.shogun.db.getUserByAlias(withUsername);
|
|
99553
99560
|
const otherUserPub = otherUserData?.userPub;
|
|
99554
|
-
console.log(`[SHIP-01] Other user pub: ${otherUserPub?.substring(0, 20) || 'not found'}...`);
|
|
99555
99561
|
// Use .map() instead of .then() to iterate all messages
|
|
99556
99562
|
return new Promise((resolve) => {
|
|
99557
99563
|
const messages = [];
|
|
99558
99564
|
let messageCount = 0;
|
|
99559
|
-
this.shogun.db.gun
|
|
99565
|
+
this.shogun.db.gun
|
|
99566
|
+
.get(SHIP_01.NODES.MESSAGES)
|
|
99567
|
+
.map()
|
|
99568
|
+
.once(async (msgData, messageId) => {
|
|
99560
99569
|
// Skip metadata fields
|
|
99561
|
-
if (!msgData || typeof msgData !==
|
|
99570
|
+
if (!msgData || typeof msgData !== "object" || messageId === "_") {
|
|
99562
99571
|
return;
|
|
99563
99572
|
}
|
|
99564
99573
|
messageCount++;
|
|
99565
|
-
console.log(`[SHIP-01] Checking message ${messageId}:`, {
|
|
99566
|
-
from: msgData.from?.substring(0, 20),
|
|
99567
|
-
to: msgData.to,
|
|
99568
|
-
hasContent: !!msgData.content
|
|
99569
|
-
});
|
|
99570
99574
|
try {
|
|
99571
99575
|
// Check if message is part of this conversation
|
|
99572
|
-
|
|
99573
|
-
const
|
|
99574
|
-
|
|
99575
|
-
|
|
99576
|
-
|
|
99577
|
-
fromMatch: msgData.from === userPub,
|
|
99578
|
-
toMatch: msgData.to === withUsername,
|
|
99579
|
-
receivedToMatch: msgData.to === username,
|
|
99580
|
-
receivedFromMatch: msgData.from === otherUserPub
|
|
99581
|
-
});
|
|
99576
|
+
// Fixed: Handle both username and userPub in matching
|
|
99577
|
+
const isSentToTarget = msgData.from === userPub &&
|
|
99578
|
+
(msgData.to === withUsername || msgData.to === otherUserPub);
|
|
99579
|
+
const isReceivedFromTarget = (msgData.to === username || msgData.to === userPub) &&
|
|
99580
|
+
msgData.from === otherUserPub;
|
|
99582
99581
|
if (isSentToTarget || isReceivedFromTarget) {
|
|
99583
99582
|
// Decrypt message
|
|
99584
99583
|
const decryptedContent = await this.decryptMessage(msgData.content, msgData.from);
|
|
@@ -99586,18 +99585,16 @@ class SHIP_01 {
|
|
|
99586
99585
|
from: msgData.from,
|
|
99587
99586
|
to: msgData.to,
|
|
99588
99587
|
content: decryptedContent,
|
|
99589
|
-
timestamp: parseInt(msgData.timestamp)
|
|
99588
|
+
timestamp: parseInt(msgData.timestamp),
|
|
99590
99589
|
});
|
|
99591
|
-
console.log(`[SHIP-01] β
Decrypted message from ${msgData.from.substring(0, 20)}...`);
|
|
99592
99590
|
}
|
|
99593
99591
|
}
|
|
99594
99592
|
catch (error) {
|
|
99595
|
-
|
|
99593
|
+
// Silent error - message couldn't be decrypted
|
|
99596
99594
|
}
|
|
99597
99595
|
});
|
|
99598
99596
|
// Wait a bit for GunDB to return all messages, then resolve
|
|
99599
99597
|
setTimeout(() => {
|
|
99600
|
-
console.log(`[SHIP-01] Found ${messages.length} messages out of ${messageCount} total`);
|
|
99601
99598
|
const sorted = messages.sort((a, b) => a.timestamp - b.timestamp);
|
|
99602
99599
|
resolve(sorted);
|
|
99603
99600
|
}, 2000);
|
|
@@ -99627,7 +99624,7 @@ class SHIP_01 {
|
|
|
99627
99624
|
const derived = await (0, derive_1.default)(seaPair.priv, null, {
|
|
99628
99625
|
includeSecp256k1Ethereum: true,
|
|
99629
99626
|
includeP256: false,
|
|
99630
|
-
includeSecp256k1Bitcoin: false
|
|
99627
|
+
includeSecp256k1Bitcoin: false,
|
|
99631
99628
|
});
|
|
99632
99629
|
return derived.secp256k1Ethereum.address;
|
|
99633
99630
|
}
|
|
@@ -99636,7 +99633,7 @@ class SHIP_01 {
|
|
|
99636
99633
|
// Fallback: hash della chiave pubblica
|
|
99637
99634
|
const fallbackKey = publicKey || "unknown";
|
|
99638
99635
|
const hash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(fallbackKey));
|
|
99639
|
-
return ethers_1.ethers.getAddress(
|
|
99636
|
+
return ethers_1.ethers.getAddress("0x" + hash.slice(-40));
|
|
99640
99637
|
}
|
|
99641
99638
|
}
|
|
99642
99639
|
/**
|
|
@@ -99647,181 +99644,12 @@ class SHIP_01 {
|
|
|
99647
99644
|
}
|
|
99648
99645
|
}
|
|
99649
99646
|
exports.SHIP_01 = SHIP_01;
|
|
99650
|
-
//
|
|
99651
|
-
|
|
99652
|
-
|
|
99653
|
-
|
|
99654
|
-
|
|
99655
|
-
|
|
99656
|
-
// const app = new SHIP_01({
|
|
99657
|
-
// gunOptions: {
|
|
99658
|
-
// peers: ["https://relay.shogun-eco.xyz/gun","https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun","https://peer.wallie.io/gun"],
|
|
99659
|
-
// radisk: false,
|
|
99660
|
-
// localStorage:false,
|
|
99661
|
-
// }
|
|
99662
|
-
// });
|
|
99663
|
-
// // 2. Signup (prima volta)
|
|
99664
|
-
// console.log("π Registrazione nuovo utente...");
|
|
99665
|
-
// const signupResult = await app.signup("alice", "password123");
|
|
99666
|
-
// if (!signupResult.success) {
|
|
99667
|
-
// console.log("βΉοΈ Utente giΓ esistente, procedo con login");
|
|
99668
|
-
// } else {
|
|
99669
|
-
// console.log("β
Utente registrato!");
|
|
99670
|
-
// console.log(` Username: alice`);
|
|
99671
|
-
// console.log(` Public Key: ${signupResult.userPub}`);
|
|
99672
|
-
// console.log(` Derived Address: ${signupResult.derivedAddress}\n`);
|
|
99673
|
-
// }
|
|
99674
|
-
// // 3. Login
|
|
99675
|
-
// console.log("π Login...");
|
|
99676
|
-
// const loginResult = await app.login("alice", "password123");
|
|
99677
|
-
// if (!loginResult.success) {
|
|
99678
|
-
// console.error("β Login fallito:", loginResult.error);
|
|
99679
|
-
// return;
|
|
99680
|
-
// }
|
|
99681
|
-
// console.log("β
Login effettuato!");
|
|
99682
|
-
// console.log(` - Autenticazione: Shogun Core (Username/Password)`);
|
|
99683
|
-
// console.log(` - Storage: GunDB decentralizzato P2P\n`);
|
|
99684
|
-
// // 4. Pubblica chiave pubblica
|
|
99685
|
-
// console.log("π’ Pubblicazione chiave pubblica...");
|
|
99686
|
-
// await app.publishPublicKey();
|
|
99687
|
-
// // 5. Ascolta messaggi in arrivo
|
|
99688
|
-
// console.log("\nπ In ascolto di messaggi...\n");
|
|
99689
|
-
// await app.listenForMessages((message) => {
|
|
99690
|
-
// console.log(`π¨ Nuovo messaggio da ${message.from.substring(0, 10)}...:`);
|
|
99691
|
-
// console.log(` Contenuto: ${message.content}`);
|
|
99692
|
-
// console.log(` Timestamp: ${new Date(message.timestamp).toLocaleString()}\n`);
|
|
99693
|
-
// });
|
|
99694
|
-
// // 6. Invia un messaggio
|
|
99695
|
-
// const recipientUsername = "bob";
|
|
99696
|
-
// console.log(`π€ Invio messaggio a ${recipientUsername}...`);
|
|
99697
|
-
// const result = await app.sendMessage(
|
|
99698
|
-
// recipientUsername,
|
|
99699
|
-
// "Hello Bob! This is a secure message using Shogun Core"
|
|
99700
|
-
// );
|
|
99701
|
-
// if (result.success) {
|
|
99702
|
-
// console.log("β
Messaggio inviato!");
|
|
99703
|
-
// console.log(` Message ID: ${result.messageId}`);
|
|
99704
|
-
// console.log(` Storage: GunDB P2P (gratis!)`);
|
|
99705
|
-
// }
|
|
99706
|
-
// // 7. Recupera storico conversazione
|
|
99707
|
-
// console.log("\nπ Recupero storico messaggi...");
|
|
99708
|
-
// const history = await app.getMessageHistory(recipientUsername);
|
|
99709
|
-
// console.log(`\n㪠Conversazione con ${recipientUsername} (${history.length} messaggi):`);
|
|
99710
|
-
// history.forEach((msg, i) => {
|
|
99711
|
-
// const isMe = msg.from === loginResult.userPub;
|
|
99712
|
-
// console.log(`${i + 1}. ${isMe ? 'Tu' : 'Loro'}: ${msg.content}`);
|
|
99713
|
-
// });
|
|
99714
|
-
// }
|
|
99715
|
-
// ============================================================================
|
|
99716
|
-
// 9. VANTAGGI DELL'ARCHITETTURA
|
|
99717
|
-
// ============================================================================
|
|
99718
|
-
/**
|
|
99719
|
-
* VANTAGGI DI QUESTA ARCHITETTURA:
|
|
99720
|
-
*
|
|
99721
|
-
* 1. SEMPLICITΓ:
|
|
99722
|
-
* - Solo username/password (nessun wallet necessario)
|
|
99723
|
-
* - Nessun gas fee o transazioni blockchain
|
|
99724
|
-
* - Setup in pochi secondi
|
|
99725
|
-
*
|
|
99726
|
-
* 2. DECENTRALIZZAZIONE COMPLETA:
|
|
99727
|
-
* - Storage P2P su GunDB
|
|
99728
|
-
* - Nessun server centrale
|
|
99729
|
-
* - Censorship resistant
|
|
99730
|
-
* - User sovereignty
|
|
99731
|
-
*
|
|
99732
|
-
* 3. COSTI ZERO:
|
|
99733
|
-
* - Nessun costo per messaggi
|
|
99734
|
-
* - Nessun costo per storage
|
|
99735
|
-
* - Completamente gratis
|
|
99736
|
-
*
|
|
99737
|
-
* 4. END-TO-END ENCRYPTION:
|
|
99738
|
-
* - Messaggi crittografati con ECDH (Elliptic Curve Diffie-Hellman)
|
|
99739
|
-
* - SEA.secret deriva shared secret da epub (encryption public key)
|
|
99740
|
-
* - SEA.encrypt cripta con AES-GCM
|
|
99741
|
-
* - Solo mittente e destinatario possono leggere i messaggi
|
|
99742
|
-
* - Nessun server o relay puΓ² leggere il contenuto
|
|
99743
|
-
*
|
|
99744
|
-
* 5. IDENTITΓ DECENTRALIZZATA:
|
|
99745
|
-
* - Chiave pubblica GunDB come identitΓ
|
|
99746
|
-
* - PuΓ² essere derivata in address Ethereum se necessario
|
|
99747
|
-
* - Portabile tra diverse applicazioni
|
|
99748
|
-
*
|
|
99749
|
-
* 6. REAL-TIME:
|
|
99750
|
-
* - Messaggi in tempo reale
|
|
99751
|
-
* - Sincronizzazione automatica
|
|
99752
|
-
* - Listener reattivi
|
|
99753
|
-
*
|
|
99754
|
-
* 7. OFFLINE-FIRST:
|
|
99755
|
-
* - Funziona anche offline
|
|
99756
|
-
* - Sincronizzazione automatica al riconnect
|
|
99757
|
-
* - GunDB gestisce conflitti automaticamente
|
|
99758
|
-
*
|
|
99759
|
-
* COME FUNZIONA LA CRITTOGRAFIA:
|
|
99760
|
-
*
|
|
99761
|
-
* 1. SETUP - Ogni utente ha un SEA pair:
|
|
99762
|
-
* - pub: chiave pubblica di signing
|
|
99763
|
-
* - priv: chiave privata di signing
|
|
99764
|
-
* - epub: chiave pubblica di encryption (per ECDH)
|
|
99765
|
-
* - epriv: chiave privata di encryption (per ECDH)
|
|
99766
|
-
*
|
|
99767
|
-
* 2. PUBBLICAZIONE CHIAVI:
|
|
99768
|
-
* - Ogni utente pubblica il suo epub su GunDB
|
|
99769
|
-
* - Altri possono trovarlo per criptare messaggi
|
|
99770
|
-
*
|
|
99771
|
-
* 3. INVIO MESSAGGIO (Alice β Bob):
|
|
99772
|
-
* a) Alice ottiene l'epub di Bob da GunDB
|
|
99773
|
-
* b) SEA.secret(bob.epub, alice.pair) β shared_secret (ECDH)
|
|
99774
|
-
* c) SEA.encrypt(message, shared_secret) β encrypted_message
|
|
99775
|
-
* d) Alice salva encrypted_message su GunDB
|
|
99776
|
-
*
|
|
99777
|
-
* 4. RICEZIONE MESSAGGIO (Bob riceve):
|
|
99778
|
-
* a) Bob legge encrypted_message da GunDB
|
|
99779
|
-
* b) Bob ottiene l'epub di Alice
|
|
99780
|
-
* c) SEA.secret(alice.epub, bob.pair) β shared_secret (stesso!)
|
|
99781
|
-
* d) SEA.decrypt(encrypted_message, shared_secret) β message
|
|
99782
|
-
*
|
|
99783
|
-
* 5. SICUREZZA:
|
|
99784
|
-
* - Shared secret derivato con ECDH (mai trasmesso)
|
|
99785
|
-
* - Solo Alice e Bob possono derivare lo stesso secret
|
|
99786
|
-
* - Messaggi crittografati con AES-256-GCM
|
|
99787
|
-
* - Forward secrecy se chiavi sono ruotate
|
|
99788
|
-
*
|
|
99789
|
-
* Esempio tecnico:
|
|
99790
|
-
* Alice.epub + Bob.epriv β shared_secret_AB
|
|
99791
|
-
* Bob.epub + Alice.epriv β shared_secret_AB (stesso!)
|
|
99792
|
-
*
|
|
99793
|
-
* Vantaggi:
|
|
99794
|
-
* β
End-to-end encryption
|
|
99795
|
-
* β
Perfect forward secrecy (con key rotation)
|
|
99796
|
-
* β
Nessun server puΓ² leggere i messaggi
|
|
99797
|
-
* β
Standard crittografico (ECDH + AES-GCM)
|
|
99798
|
-
* β
Una sola chiave privata da gestire
|
|
99799
|
-
* β
Address Ethereum derivabile (interoperabilitΓ )
|
|
99800
|
-
*/
|
|
99801
|
-
// ============================================================================
|
|
99802
|
-
// 10. TEST COMPLETO: Alice e Bob si scambiano messaggi
|
|
99803
|
-
// ============================================================================
|
|
99804
|
-
/**
|
|
99805
|
-
* Test completo che simula Alice e Bob che si scambiano messaggi CRITTOGRAFATI
|
|
99806
|
-
*
|
|
99807
|
-
* CRITTOGRAFIA END-TO-END:
|
|
99808
|
-
* - Ogni messaggio Γ¨ crittografato con ECDH (Elliptic Curve Diffie-Hellman)
|
|
99809
|
-
* - Solo mittente e destinatario possono leggere i messaggi
|
|
99810
|
-
* - I relay GunDB vedono solo dati crittografati
|
|
99811
|
-
*
|
|
99812
|
-
* FLOW:
|
|
99813
|
-
* 1. Alice e Bob pubblicano le loro chiavi pubbliche (epub)
|
|
99814
|
-
* 2. Alice vuole inviare a Bob:
|
|
99815
|
-
* - Ottiene bob.epub da GunDB
|
|
99816
|
-
* - SEA.secret(bob.epub, alice.pair) β shared_secret
|
|
99817
|
-
* - SEA.encrypt(message, shared_secret) β encrypted
|
|
99818
|
-
* - Salva encrypted su GunDB
|
|
99819
|
-
* 3. Bob riceve:
|
|
99820
|
-
* - Legge encrypted da GunDB
|
|
99821
|
-
* - Ottiene alice.epub
|
|
99822
|
-
* - SEA.secret(alice.epub, bob.pair) β shared_secret (stesso!)
|
|
99823
|
-
* - SEA.decrypt(encrypted, shared_secret) β message
|
|
99824
|
-
*/
|
|
99647
|
+
// GunDB Node Names - Constants for clarity
|
|
99648
|
+
SHIP_01.NODES = {
|
|
99649
|
+
MESSAGES: "messages",
|
|
99650
|
+
USERS: "users",
|
|
99651
|
+
PUBLIC_KEYS: "publicKeys",
|
|
99652
|
+
};
|
|
99825
99653
|
async function testAliceAndBob() {
|
|
99826
99654
|
console.log("π§ͺ TEST: Alice e Bob - Conversazione Crittografata E2E\n");
|
|
99827
99655
|
console.log("=".repeat(60));
|
|
@@ -99843,14 +99671,14 @@ async function testAliceAndBob() {
|
|
|
99843
99671
|
}
|
|
99844
99672
|
await alice.publishPublicKey();
|
|
99845
99673
|
// Aspetta che la chiave sia sincronizzata
|
|
99846
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
99674
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
99847
99675
|
// Setup Bob
|
|
99848
99676
|
console.log("\nπ¨ BOB - Setup");
|
|
99849
99677
|
console.log("-".repeat(60));
|
|
99850
99678
|
const bob = new SHIP_01({
|
|
99851
99679
|
gunOptions: {
|
|
99852
99680
|
peers: ["https://peer.wallie.io/gun"],
|
|
99853
|
-
radisk: true
|
|
99681
|
+
radisk: true,
|
|
99854
99682
|
},
|
|
99855
99683
|
});
|
|
99856
99684
|
// Bob signup/login
|
|
@@ -99862,7 +99690,7 @@ async function testAliceAndBob() {
|
|
|
99862
99690
|
}
|
|
99863
99691
|
await bob.publishPublicKey();
|
|
99864
99692
|
// Aspetta che la chiave sia sincronizzata
|
|
99865
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
99693
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
99866
99694
|
console.log("\n" + "=".repeat(60));
|
|
99867
99695
|
console.log("π¬ CONVERSAZIONE");
|
|
99868
99696
|
console.log("=".repeat(60));
|
|
@@ -99884,31 +99712,31 @@ async function testAliceAndBob() {
|
|
|
99884
99712
|
console.log(` Timestamp: ${new Date(msg.timestamp).toLocaleTimeString()}`);
|
|
99885
99713
|
});
|
|
99886
99714
|
// Aspetta che i listener siano pronti
|
|
99887
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99715
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
99888
99716
|
// Alice invia messaggio a Bob
|
|
99889
99717
|
console.log("\n[Alice invia] π€");
|
|
99890
99718
|
const msg1 = await alice.sendMessage("bob", "Ciao Bob! Come stai? π");
|
|
99891
99719
|
console.log(` β
Inviato: "${msg1.messageId}"`);
|
|
99892
99720
|
// Aspetta che Bob riceva
|
|
99893
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99721
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
99894
99722
|
// Bob risponde ad Alice
|
|
99895
99723
|
console.log("\n[Bob invia] π€");
|
|
99896
99724
|
const msg2 = await bob.sendMessage("alice", "Ciao Alice! Tutto bene, grazie! Tu? π");
|
|
99897
99725
|
console.log(` β
Inviato: "${msg2.messageId}"`);
|
|
99898
99726
|
// Aspetta che Alice riceva
|
|
99899
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99727
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
99900
99728
|
// Alice risponde
|
|
99901
99729
|
console.log("\n[Alice invia] π€");
|
|
99902
99730
|
const msg3 = await alice.sendMessage("bob", "Anch'io benissimo! Questo sistema di messaggistica Γ¨ fantastico! π");
|
|
99903
99731
|
console.log(` β
Inviato: "${msg3.messageId}"`);
|
|
99904
99732
|
// Aspetta che Bob riceva
|
|
99905
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99733
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
99906
99734
|
// Bob conclude
|
|
99907
99735
|
console.log("\n[Bob invia] π€");
|
|
99908
99736
|
const msg4 = await bob.sendMessage("alice", "Vero! Zero costi, decentralizzato e veloce! πͺ");
|
|
99909
99737
|
console.log(` β
Inviato: "${msg4.messageId}"`);
|
|
99910
99738
|
// Aspetta finale
|
|
99911
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
99739
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
99912
99740
|
// Mostra statistiche
|
|
99913
99741
|
console.log("\n" + "=".repeat(60));
|
|
99914
99742
|
console.log("π STATISTICHE FINALI");
|
|
@@ -99954,8 +99782,6 @@ async function testAliceAndBob() {
|
|
|
99954
99782
|
}
|
|
99955
99783
|
// Esegui esempio o test
|
|
99956
99784
|
if (__webpack_require__.c[__webpack_require__.s] === module) {
|
|
99957
|
-
// Scegli quale eseguire decommentando una delle due righe:
|
|
99958
|
-
// main().catch(console.error); // Esempio singolo utente
|
|
99959
99785
|
testAliceAndBob().catch(console.error); // Test completo Alice & Bob
|
|
99960
99786
|
}
|
|
99961
99787
|
|