@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.
101 lines (100 loc) • 3.72 kB
JavaScript
/**
* SERVER-SIDE SIGNATURE DECODER
* ============================
*
* Utilities for decoding base64 attestation signatures on the server side.
* Use this in your backend to decode signatures received from the Mona Attest SDK.
*/
/**
* Decode a base64 attestation signature from the Mona Attest SDK
*
* @param signatureBase64 - The base64 encoded signature from the SDK
* @returns Decoded signature data ready for WebAuthn verification
*/
export function decodeAttestationSignature(signatureBase64) {
try {
// Decode the base64 outer wrapper
const signatureJson = atob(signatureBase64);
const signatureData = JSON.parse(signatureJson);
// Helper function to convert base64 to Uint8Array
const base64ToUint8Array = (base64) => {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
};
// Decode all binary data back to Uint8Arrays
const decoded = {
sessionId: signatureData.sessionId,
credentialId: signatureData.credentialId,
authenticatorData: base64ToUint8Array(signatureData.authenticatorData),
clientDataJSON: base64ToUint8Array(signatureData.clientDataJSON),
signature: base64ToUint8Array(signatureData.signature),
userHandle: signatureData.userHandle ? base64ToUint8Array(signatureData.userHandle) : null,
type: signatureData.type
};
return decoded;
}
catch (error) {
throw new Error(`Failed to decode attestation signature: ${error.message}`);
}
}
/**
* Convert decoded signature to WebAuthn assertion response format
*
* @param decoded - Decoded signature from decodeAttestationSignature
* @returns WebAuthn assertion response object for verification
*/
export function toWebAuthnAssertionResponse(decoded) {
return {
id: decoded.credentialId,
rawId: decoded.credentialId, // For WebAuthn verification, id and rawId are the same
response: {
authenticatorData: decoded.authenticatorData,
clientDataJSON: decoded.clientDataJSON,
signature: decoded.signature,
userHandle: decoded.userHandle
},
type: decoded.type
};
}
/**
* Example usage for Express.js backend:
*
* ```javascript
* const { decodeAttestationSignature, toWebAuthnAssertionResponse } = require('@attesttool/sdk/server');
*
* app.post('/api/payments/execute-with-attestation', (req, res) => {
* const signatureBase64 = req.headers['x-attestation-signature'];
* const { sessionId, paymentData } = req.body;
*
* try {
* // Decode the signature
* const decoded = decodeAttestationSignature(signatureBase64);
*
* // Verify with Mona Attest backend
* const webauthnResponse = toWebAuthnAssertionResponse(decoded);
* const verificationResult = await fetch('https://api.attest.ng/api/passkey/complete-attest', {
* method: 'POST',
* headers: { 'Content-Type': 'application/json' },
* body: JSON.stringify({
* sessionId: decoded.sessionId,
* assertionResponse: webauthnResponse
* })
* });
*
* if (verificationResult.verified) {
* // Process the payment
* await processPayment(paymentData);
* res.json({ success: true });
* } else {
* res.status(400).json({ error: 'Signature verification failed' });
* }
* } catch (error) {
* res.status(400).json({ error: error.message });
* }
* });
* ```
*/