UNPKG

@usemona/attest-backend-sdk

Version:

Mona Attest Backend SDK - Secure server-side verification for cryptographic attestations and digital signatures. Provides robust signature validation, user verification, and enterprise-grade security for Node.js applications.

125 lines (124 loc) 5.16 kB
export class AttestBackendSDK { constructor(config = {}) { // Use provided URL or default this.apiUrl = config.apiUrl || 'https://api.attest.ng'; console.log('🔧 AttestBackendSDK Constructor:', { apiUrl: this.apiUrl }); } /** * Verify an attestation token against the original API call */ async verifyAttestation(attestationToken, originalAPICall) { try { // Step 1: Extract session ID and signature from token const { sessionId, signatureBase64 } = this.parseAttestationToken(attestationToken); // Step 2: Pass everything to Mona Attest backend for verification return await this.verifyWithAttest(sessionId, signatureBase64, originalAPICall); } catch (error) { return { verified: false, error: error instanceof Error ? error.message : 'Verification failed' }; } } // ============================================================================ // PRIVATE HELPER METHODS // ============================================================================ /** * Verify attestation by calling Mona Attest backend with original API call data */ async verifyWithAttest(sessionId, signatureBase64, originalAPICall) { try { // Parse the signature data back to the format expected by complete-attest const signatureData = JSON.parse(atob(signatureBase64)); // Create assertion response in the format expected by Mona Attest backend const assertionResponse = { id: signatureData.credentialId, rawId: signatureData.credentialId, // Use same as id for compatibility type: signatureData.type || 'public-key', response: { authenticatorData: signatureData.authenticatorData, clientDataJSON: signatureData.clientDataJSON, signature: signatureData.signature, userHandle: signatureData.userHandle } }; const completeAttestUrl = `${this.apiUrl}/api/passkey/complete-attest`; const response = await fetch(completeAttestUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Attestation-Session': sessionId }, body: JSON.stringify({ assertionResponse, // Pass original API call data for independent verification by Mona Attest backend originalAPICall: { method: originalAPICall.method, uri: originalAPICall.uri, body: originalAPICall.body, headers: originalAPICall.headers } }) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Verification API failed: ${response.status} ${response.statusText} - ${errorText}`); } const verificationResult = await response.json(); if (verificationResult.success && verificationResult.verified) { return { verified: true, originalPayload: originalAPICall.body, signatureData: verificationResult.signedPayload, keyId: verificationResult.keyId, attestationId: verificationResult.attestationId, timestamp: verificationResult.timestamp }; } else { return { verified: false, error: verificationResult.message || 'Signature verification failed' }; } } catch (error) { return { verified: false, error: error instanceof Error ? error.message : 'Verification failed' }; } } /** * Parse attestation token to extract session ID and signature */ parseAttestationToken(attestationToken) { try { if (!attestationToken || typeof attestationToken !== 'string') { throw new Error('Invalid attestation token format'); } // Attestation token format: "sessionId.signatureBase64" const parts = attestationToken.split('.'); if (parts.length !== 2) { throw new Error('Invalid attestation token format - expected sessionId.signature'); } const [sessionId, signatureBase64] = parts; if (!sessionId || !signatureBase64) { throw new Error('Invalid attestation token - missing sessionId or signature'); } return { sessionId, signatureBase64 }; } catch (error) { throw error; } } /** * Get API URL */ getApiUrl() { return this.apiUrl; } }