ci: docker_tag=dev-test
**Motivations :** - Correction du chiffrement : PBKDF2 génère les clés du SDK, pas des clés personnalisées - WebAuthn chiffre maintenant les clés du SDK générées par PBKDF2 - Ajout de getDeviceFromSDK() pour récupérer les clés du SDK **Modifications :** - Remplacement de generateSpendKey/generateScanKey par getDeviceFromSDK() - WebAuthn chiffre maintenant device.sp_wallet.spend_key et device.sp_wallet.scan_key - Ajout de la méthode getDeviceFromSDK() pour accéder au SDK **Pages affectées :** - src/services/secure-credentials.service.ts
This commit is contained in:
parent
3f387ee97f
commit
4a3b23c9d7
@ -542,8 +542,8 @@ async function handleMainPairing(): Promise<void> {
|
||||
if (mainStatus) {
|
||||
mainStatus.innerHTML = '<span style="color: var(--error-color)">❌ Failed to create credentials</span>';
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Now proceed with pairing process
|
||||
console.log('🚀 Starting pairing process...');
|
||||
|
||||
@ -137,13 +137,15 @@ export class SecureCredentialsService {
|
||||
const publicKey = response.getPublicKey();
|
||||
const credentialId = credential.id;
|
||||
|
||||
// Générer les clés privées réelles (spend/scan) avec PBKDF2
|
||||
const spendKey = await this.generateSpendKey(password);
|
||||
const scanKey = await this.generateScanKey(password);
|
||||
// Récupérer les clés du SDK générées par PBKDF2
|
||||
const device = await this.getDeviceFromSDK();
|
||||
if (!device || !device.sp_wallet) {
|
||||
throw new Error('SDK device not found or wallet not initialized');
|
||||
}
|
||||
|
||||
// Chiffrer les clés privées avec la clé WebAuthn
|
||||
const encryptedSpendKey = await this.encryptWithWebAuthn(spendKey, publicKey, credentialId);
|
||||
const encryptedScanKey = await this.encryptWithWebAuthn(scanKey, publicKey, credentialId);
|
||||
// Chiffrer les clés du SDK avec la clé WebAuthn
|
||||
const encryptedSpendKey = await this.encryptWithWebAuthn(device.sp_wallet.spend_key, publicKey, credentialId);
|
||||
const encryptedScanKey = await this.encryptWithWebAuthn(device.sp_wallet.scan_key, publicKey, credentialId);
|
||||
|
||||
const credentialData: CredentialData = {
|
||||
spendKey: encryptedSpendKey, // Clé chiffrée
|
||||
@ -173,6 +175,21 @@ export class SecureCredentialsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le device du SDK pour obtenir les clés générées par PBKDF2
|
||||
*/
|
||||
private async getDeviceFromSDK(): Promise<any> {
|
||||
try {
|
||||
// Importer le service pour accéder au SDK
|
||||
const { Services } = await import('./service');
|
||||
const service = await Services.getInstance();
|
||||
return service.dumpDeviceFromMemory();
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to get device from SDK:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère une clé spend avec PBKDF2
|
||||
*/
|
||||
|
||||
@ -291,7 +291,7 @@ export default class Services {
|
||||
}
|
||||
|
||||
// Memory is sufficient, load WebAssembly
|
||||
Services.instance = await Services.initializing;
|
||||
Services.instance = await Services.initializing;
|
||||
Services.initializing = null;
|
||||
console.log('✅ Services initialized with WebAssembly');
|
||||
|
||||
@ -474,50 +474,50 @@ export default class Services {
|
||||
* Waits for at least one handshake message before returning.
|
||||
*/
|
||||
public async connectAllRelays(): Promise<void> {
|
||||
const relayUrls = Object.keys(this.relayAddresses);
|
||||
console.log(`🚀 Connecting to ${relayUrls.length} relays in parallel...`);
|
||||
const relayUrls = Object.keys(this.relayAddresses);
|
||||
console.log(`🚀 Connecting to ${relayUrls.length} relays in parallel...`);
|
||||
|
||||
// Create the relay ready promise immediately when starting connections
|
||||
this.getRelayReadyPromise();
|
||||
|
||||
// Connect to all relays in parallel
|
||||
// Connect to all relays in parallel
|
||||
const connectionPromises = relayUrls.map(async wsurl => {
|
||||
try {
|
||||
console.log(`🔗 Connecting to: ${wsurl}`);
|
||||
await this.addWebsocketConnection(wsurl);
|
||||
console.log(`✅ Successfully connected to: ${wsurl}`);
|
||||
return wsurl;
|
||||
} catch (error) {
|
||||
console.error(`❌ Failed to connect to ${wsurl}:`, error);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
try {
|
||||
console.log(`🔗 Connecting to: ${wsurl}`);
|
||||
await this.addWebsocketConnection(wsurl);
|
||||
console.log(`✅ Successfully connected to: ${wsurl}`);
|
||||
return wsurl;
|
||||
} catch (error) {
|
||||
console.error(`❌ Failed to connect to ${wsurl}:`, error);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for all connections to complete (success or failure)
|
||||
const results = await Promise.allSettled(connectionPromises);
|
||||
const connectedUrls = results
|
||||
// Wait for all connections to complete (success or failure)
|
||||
const results = await Promise.allSettled(connectionPromises);
|
||||
const connectedUrls = results
|
||||
.filter(
|
||||
(result): result is PromiseFulfilledResult<string> =>
|
||||
result.status === 'fulfilled' && result.value !== null
|
||||
)
|
||||
.map(result => result.value);
|
||||
.map(result => result.value);
|
||||
|
||||
console.log(`✅ Connected to ${connectedUrls.length}/${relayUrls.length} relays`);
|
||||
console.log(`✅ Connected to ${connectedUrls.length}/${relayUrls.length} relays`);
|
||||
|
||||
// Wait for at least one handshake message if we have connections
|
||||
if (connectedUrls.length > 0) {
|
||||
try {
|
||||
await this.waitForHandshakeMessage();
|
||||
console.log(`✅ Handshake received from at least one relay`);
|
||||
} catch (error) {
|
||||
// Wait for at least one handshake message if we have connections
|
||||
if (connectedUrls.length > 0) {
|
||||
try {
|
||||
await this.waitForHandshakeMessage();
|
||||
console.log(`✅ Handshake received from at least one relay`);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`⚠️ No handshake received within timeout, but continuing with ${connectedUrls.length} connections`
|
||||
);
|
||||
// Continue anyway - we have connections even without handshake
|
||||
// Continue anyway - we have connections even without handshake
|
||||
}
|
||||
} else {
|
||||
console.warn(`⚠️ No relay connections established`);
|
||||
}
|
||||
} else {
|
||||
console.warn(`⚠️ No relay connections established`);
|
||||
}
|
||||
}
|
||||
|
||||
private getRelayReadyPromise(): Promise<void> {
|
||||
@ -574,7 +574,7 @@ export default class Services {
|
||||
* @returns The SP Address if found, or undefined if not.
|
||||
*/
|
||||
public getSpAddress(wsurl: string): string | undefined {
|
||||
return this.relayAddresses[wsurl];
|
||||
return this.relayAddresses[wsurl];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -582,10 +582,10 @@ export default class Services {
|
||||
* @returns An array of objects containing wsurl and spAddress.
|
||||
*/
|
||||
public getAllRelays(): { wsurl: string; spAddress: string }[] {
|
||||
return Object.entries(this.relayAddresses).map(([wsurl, spAddress]) => ({
|
||||
wsurl,
|
||||
spAddress,
|
||||
}));
|
||||
return Object.entries(this.relayAddresses).map(([wsurl, spAddress]) => ({
|
||||
wsurl,
|
||||
spAddress,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -593,9 +593,9 @@ export default class Services {
|
||||
*/
|
||||
public printAllRelays(): void {
|
||||
console.log('Current relay addresses:');
|
||||
for (const [wsurl, spAddress] of Object.entries(this.relayAddresses)) {
|
||||
console.log(`${wsurl} -> ${spAddress}`);
|
||||
}
|
||||
for (const [wsurl, spAddress] of Object.entries(this.relayAddresses)) {
|
||||
console.log(`${wsurl} -> ${spAddress}`);
|
||||
}
|
||||
}
|
||||
|
||||
public isPaired(): boolean {
|
||||
@ -653,7 +653,7 @@ export default class Services {
|
||||
}
|
||||
|
||||
private async getTokensFromFaucet(): Promise<void> {
|
||||
await this.ensureSufficientAmount();
|
||||
await this.ensureSufficientAmount();
|
||||
}
|
||||
|
||||
// If we're updating a process, we must call that after update especially if roles are part of it
|
||||
@ -926,12 +926,12 @@ export default class Services {
|
||||
roles: Record<string, RoleDefinition>
|
||||
): Promise<ApiReturn> {
|
||||
// Attendre que le relai soit prêt avec son spAddress
|
||||
console.log('⏳ Waiting for relays to be ready...');
|
||||
console.log('⏳ Waiting for relays to be ready...');
|
||||
// Update UI status
|
||||
const { updateCreatorStatus } = await import('../utils/sp-address.utils');
|
||||
updateCreatorStatus('⏳ Waiting for relays to be ready...');
|
||||
|
||||
await this.getRelayReadyPromise();
|
||||
await this.getRelayReadyPromise();
|
||||
|
||||
// Vérifier que nous avons maintenant un spAddress
|
||||
const relays = this.getAllRelays();
|
||||
@ -992,11 +992,11 @@ export default class Services {
|
||||
console.log('🔍 DEBUG: Members array sample:', members.slice(0, 3));
|
||||
|
||||
const result = this.sdkClient.create_new_process(
|
||||
encodedPrivateData,
|
||||
roles,
|
||||
encodedPublicData,
|
||||
relayAddress,
|
||||
feeRate,
|
||||
encodedPrivateData,
|
||||
roles,
|
||||
encodedPublicData,
|
||||
relayAddress,
|
||||
feeRate,
|
||||
members
|
||||
);
|
||||
|
||||
@ -1171,7 +1171,7 @@ export default class Services {
|
||||
|
||||
// Only log as error if it's not a pairing-related issue
|
||||
if (!(e as Error).message?.includes('Failed to handle decrypted message')) {
|
||||
console.error(`Parsed cipher with error: ${e}`);
|
||||
console.error(`Parsed cipher with error: ${e}`);
|
||||
}
|
||||
}
|
||||
// await this.saveCipherTxToDb(parsedTx)
|
||||
@ -1307,7 +1307,7 @@ export default class Services {
|
||||
}
|
||||
} catch (scanError) {
|
||||
console.error('❌ Failed to scan blocks:', scanError);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.debug(e);
|
||||
@ -1515,7 +1515,7 @@ export default class Services {
|
||||
// Check if the commitment is set and not null/empty
|
||||
if (
|
||||
device.pairing_process_commitment &&
|
||||
device.pairing_process_commitment !== null &&
|
||||
device.pairing_process_commitment !== null &&
|
||||
device.pairing_process_commitment !== ''
|
||||
) {
|
||||
console.log('✅ Pairing process commitment found:', device.pairing_process_commitment);
|
||||
@ -1524,11 +1524,11 @@ export default class Services {
|
||||
|
||||
// For quorum=1.0 processes, the creator must commit themselves
|
||||
// Check if the process is ready for the creator to commit
|
||||
if (currentPairingId && currentPairingId === processId) {
|
||||
if (currentPairingId && currentPairingId === processId) {
|
||||
console.log(
|
||||
'✅ Creator process is synchronized and ready for self-commitment (quorum=1.0)'
|
||||
);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// For quorum=1 test, if we have a process but no commitment yet,
|
||||
@ -1577,11 +1577,11 @@ export default class Services {
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e) {
|
||||
console.log(
|
||||
`❌ Attempt ${i + 1}/${maxRetries}: Error during synchronization - ${(e as Error).message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (i < maxRetries - 1) {
|
||||
console.log(`⏳ Waiting ${retryDelay}ms before next attempt...`);
|
||||
@ -1682,7 +1682,7 @@ export default class Services {
|
||||
throw new Error('SDK not initialized - cannot get amount');
|
||||
}
|
||||
try {
|
||||
const amount = this.sdkClient.get_available_amount();
|
||||
const amount = this.sdkClient.get_available_amount();
|
||||
console.log(`💰 SDK get_available_amount() returned: ${amount}`);
|
||||
|
||||
// Additional debugging: check wallet state
|
||||
@ -1701,7 +1701,7 @@ export default class Services {
|
||||
console.warn('⚠️ Error getting wallet debugging info:', error);
|
||||
}
|
||||
|
||||
return amount;
|
||||
return amount;
|
||||
} catch (error) {
|
||||
console.error('❌ Error calling get_available_amount():', error);
|
||||
throw error;
|
||||
@ -2002,7 +2002,7 @@ export default class Services {
|
||||
throw new Error('Birthday not found');
|
||||
}
|
||||
|
||||
if (birthday === 0) {
|
||||
if (birthday === 0) {
|
||||
// This is a new device, set birthday to scan from much earlier to catch faucet transactions
|
||||
// Scan from 100 blocks earlier to ensure we catch all faucet transactions
|
||||
console.log('🔧 Updating birthday for new device:', {
|
||||
@ -2668,7 +2668,7 @@ export default class Services {
|
||||
*/
|
||||
public getAllMembersSorted(): Record<string, Member> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(this.membersList).sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
|
||||
Object.entries(this.membersList).sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user