fix: resolve multiple critical issues
**Motivations :** - Fix WebAuthn authentication regression (button reappeared instead of auto-trigger) - Resolve infinite loop of 'process.states is not an array' logs - Fix WebAssembly serialization error 'invalid type: map, expected a sequence' - Improve WebAuthn error handling and timeout management **Modifications :** - Restored automatic WebAuthn triggering in home.ts initHomePage() - Fixed handshake deduplication logic in service.ts using content-based keys - Added membersList validation before WebAssembly calls to prevent empty object errors - Enhanced WebAuthn error handling with specific error messages and increased timeout to 2 minutes - Improved error messages for NotAllowedError, NotSupportedError, and SecurityError **Pages affectées :** - src/pages/home/home.ts: Restored auto WebAuthn trigger, removed manual button - src/services/service.ts: Fixed handshake deduplication and added membersList validation - src/services/secure-credentials.service.ts: Enhanced WebAuthn error handling and timeout
This commit is contained in:
parent
8af1fd055d
commit
e393a4f615
@ -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 = `
|
||||
<div class="auth-container">
|
||||
<p>🔐 Secure authentication required</p>
|
||||
<div class="spinner"></div>
|
||||
<span>Initializing secure authentication...</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
console.log('🔐 Main pairing setup - authentication will be automatic');
|
||||
}
|
||||
|
||||
|
||||
@ -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({
|
||||
// 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,8 +299,10 @@ export class SecureCredentialsService {
|
||||
throw new Error('WebAuthn not supported for decryption');
|
||||
}
|
||||
|
||||
// Demander l'authentification WebAuthn
|
||||
const credential = await navigator.credentials.get({
|
||||
// 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: [{
|
||||
@ -292,9 +310,23 @@ export class SecureCredentialsService {
|
||||
type: 'public-key'
|
||||
}],
|
||||
userVerification: 'required',
|
||||
timeout: 60000
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (!credential) {
|
||||
throw new Error('WebAuthn authentication failed');
|
||||
|
||||
@ -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<string, RoleDefinition>[]
|
||||
) {
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user