diff --git a/src/pages/home/home.ts b/src/pages/home/home.ts
index b75b50e..dde82cb 100755
--- a/src/pages/home/home.ts
+++ b/src/pages/home/home.ts
@@ -524,9 +524,21 @@ export function setupIframePairingButtons() {
}
}
-// Main Pairing Interface - Auto-triggered, no button needed
+// Main Pairing Interface - Automatic WebAuthn trigger
export function setupMainPairing(): void {
- // No button setup needed since authentication is automatic
+ const container = getCorrectDOM('login-4nk-component') as HTMLElement;
+ const mainStatus = container.querySelector('#main-status') as HTMLElement;
+
+ if (mainStatus) {
+ mainStatus.innerHTML = `
+
+
🔐 Secure authentication required
+
+
Initializing secure authentication...
+
+ `;
+ }
+
console.log('🔐 Main pairing setup - authentication will be automatic');
}
diff --git a/src/services/secure-credentials.service.ts b/src/services/secure-credentials.service.ts
index 8ee9507..eb109ea 100644
--- a/src/services/secure-credentials.service.ts
+++ b/src/services/secure-credentials.service.ts
@@ -99,16 +99,32 @@ export class SecureCredentialsService {
authenticatorAttachment: "platform", // Force l'authentificateur intégré
userVerification: "required"
},
- timeout: 60000,
+ timeout: 120000, // 2 minutes timeout
attestation: "direct"
};
console.log('🔐 Requesting WebAuthn credential creation for encryption key...');
- // Créer le credential WebAuthn
- const credential = await navigator.credentials.create({
- publicKey: publicKeyCredentialCreationOptions
- }) as PublicKeyCredential;
+ // Créer le credential WebAuthn avec gestion d'erreur robuste
+ let credential: PublicKeyCredential;
+ try {
+ credential = await navigator.credentials.create({
+ publicKey: publicKeyCredentialCreationOptions
+ }) as PublicKeyCredential;
+ } catch (error) {
+ if (error instanceof Error) {
+ if (error.name === 'NotAllowedError') {
+ throw new Error('WebAuthn authentication was cancelled or timed out. Please try again and complete the authentication when prompted.');
+ } else if (error.name === 'NotSupportedError') {
+ throw new Error('WebAuthn is not supported in this browser. Please use a modern browser with WebAuthn support.');
+ } else if (error.name === 'SecurityError') {
+ throw new Error('WebAuthn security error. Please ensure you are using HTTPS and try again.');
+ } else {
+ throw new Error(`WebAuthn error: ${error.message}`);
+ }
+ }
+ throw error;
+ }
if (!credential) {
throw new Error('WebAuthn credential creation failed');
@@ -283,18 +299,34 @@ export class SecureCredentialsService {
throw new Error('WebAuthn not supported for decryption');
}
- // Demander l'authentification WebAuthn
- const credential = await navigator.credentials.get({
- publicKey: {
- challenge: crypto.getRandomValues(new Uint8Array(32)),
- allowCredentials: [{
- id: new TextEncoder().encode(credentialId),
- type: 'public-key'
- }],
- userVerification: 'required',
- timeout: 60000
+ // Demander l'authentification WebAuthn avec gestion d'erreur robuste
+ let credential: PublicKeyCredential;
+ try {
+ credential = await navigator.credentials.get({
+ publicKey: {
+ challenge: crypto.getRandomValues(new Uint8Array(32)),
+ allowCredentials: [{
+ id: new TextEncoder().encode(credentialId),
+ type: 'public-key'
+ }],
+ userVerification: 'required',
+ timeout: 120000 // 2 minutes timeout
+ }
+ }) as PublicKeyCredential;
+ } catch (error) {
+ if (error instanceof Error) {
+ if (error.name === 'NotAllowedError') {
+ throw new Error('WebAuthn authentication was cancelled or timed out. Please try again and complete the authentication when prompted.');
+ } else if (error.name === 'NotSupportedError') {
+ throw new Error('WebAuthn is not supported in this browser. Please use a modern browser with WebAuthn support.');
+ } else if (error.name === 'SecurityError') {
+ throw new Error('WebAuthn security error. Please ensure you are using HTTPS and try again.');
+ } else {
+ throw new Error(`WebAuthn decryption error: ${error.message}`);
+ }
}
- }) as PublicKeyCredential;
+ throw error;
+ }
if (!credential) {
throw new Error('WebAuthn authentication failed');
diff --git a/src/services/service.ts b/src/services/service.ts
index 64bc44d..05ff366 100755
--- a/src/services/service.ts
+++ b/src/services/service.ts
@@ -897,9 +897,18 @@ export default class Services {
console.log('🔍 DEBUG: Members type:', typeof membersObj);
console.log('🔍 DEBUG: Members keys:', Object.keys(membersObj));
- // Convert object to array for WebAssembly
- const members = Object.values(membersObj);
+ // Check if membersList is empty
+ if (!membersObj || Object.keys(membersObj).length === 0) {
+ console.warn('⚠️ No members available for create_new_process, waiting for handshake...');
+ throw new Error('No members available - handshake not completed yet');
+ }
+
+ // Convert to simple array of SP addresses for WebAssembly
+ const members = Object.values(membersObj).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
console.log('🔍 DEBUG: Members array length:', members.length);
+ console.log('🔍 DEBUG: Members simplified:', members);
const result = this.sdkClient.create_new_process(
encodedPrivateData,
@@ -943,12 +952,15 @@ export default class Services {
...this.sdkClient.encode_binary(publicSplitData.binaryData),
};
try {
+ const members = Object.values(this.getAllMembers()).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
const result = this.sdkClient.update_process(
process,
encodedPrivateData,
roles,
encodedPublicData,
- Object.values(this.getAllMembers())
+ members
);
if (result.updated_process) {
await this.checkConnections(result.updated_process.current_process);
@@ -969,7 +981,10 @@ export default class Services {
await this.checkConnections(process);
}
try {
- return this.sdkClient.create_update_message(process, stateId, Object.values(this.getAllMembers()));
+ const members = Object.values(this.getAllMembers()).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
+ return this.sdkClient.create_update_message(process, stateId, members);
} catch (e) {
throw new Error(`Failed to create prd update: ${e}`);
}
@@ -981,7 +996,10 @@ export default class Services {
throw new Error('Unknown process');
}
try {
- return this.sdkClient.create_response_prd(process, stateId, Object.values(this.getAllMembers()));
+ const members = Object.values(this.getAllMembers()).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
+ return this.sdkClient.create_response_prd(process, stateId, members);
} catch (e) {
throw new Error(`Failed to create response prd: ${e}`);
}
@@ -993,7 +1011,10 @@ export default class Services {
throw new Error('Failed to get process from db');
}
try {
- const result = this.sdkClient.validate_state(process, stateId, Object.values(this.getAllMembers()));
+ const members = Object.values(this.getAllMembers()).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
+ const result = this.sdkClient.validate_state(process, stateId, members);
if (result.updated_process) {
await this.checkConnections(result.updated_process.current_process);
return result;
@@ -1049,7 +1070,9 @@ export default class Services {
}
async parseCipher(message: string) {
- const membersList = Object.values(this.getAllMembers());
+ const membersList = Object.values(this.getAllMembers()).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
const processes = await this.getProcesses();
try {
// console.log('parsing new cipher');
@@ -1080,7 +1103,9 @@ export default class Services {
return;
}
- const membersList = Object.values(this.getAllMembers());
+ const membersList = Object.values(this.getAllMembers()).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
try {
// Does the transaction spend the tip of a process?
const prevouts = this.sdkClient.get_prevouts(parsedMsg.transaction);
@@ -2178,7 +2203,7 @@ export default class Services {
}
// Add a flag to prevent processing the same handshake multiple times
- const handshakeKey = `${url}_${Date.now()}`;
+ const handshakeKey = `${url}_${JSON.stringify(handshakeMsg.processes_list)}`;
if (this.processedHandshakes && this.processedHandshakes.has(handshakeKey)) {
console.debug('Handshake already processed for', url);
return;
@@ -2479,7 +2504,9 @@ export default class Services {
roles: Record[]
) {
console.log('Requesting data from peers');
- const membersList = Object.values(this.getAllMembers());
+ const membersList = Object.values(this.getAllMembers()).map(member => ({
+ sp_addresses: member.sp_addresses
+ }));
try {
// Convert objects to strings for WASM compatibility
const rolesString = JSON.stringify(roles);