diff --git a/javascript/src/iframe/viamapi-iframe.js b/javascript/src/iframe/viamapi-iframe.js index 23d3a732bf99bea475795d39d0013911aee0ec2c..9b05cb01ad0f015c6829c49ee8b849a386c771b6 100644 --- a/javascript/src/iframe/viamapi-iframe.js +++ b/javascript/src/iframe/viamapi-iframe.js @@ -364,6 +364,12 @@ async function executeRestfulFunction(type, that, fn, config, ...args) { window.executeRestfulFunction = executeRestfulFunction; +const TRANSPARENT_PIXEL = new ImageData({ + contentType: "image/png", + contentBase64: + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" //1x1px transparent pixel +}); + function loadIdentityInternal(identityKey, pinCode) { return new Penpal.Promise(result => { getIdentityFromLocalStorage(identityKey, pinCode) @@ -1367,10 +1373,99 @@ const connection = Penpal.connectToParent({ return encodeResponse("200", "", "Document signed"); }, + /** + * Checks the state of the vCard. Current states are "disabled" and "enabled". + * @param passportUUID + * @returns {Promise<{code: *, data: *, status: *}>} + */ + async checkVCardState(passportUUID) { + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); + + if ( + !authenticationPublicKey || + !window.loadedIdentities[authenticationPublicKey] || + !extendPinCodeTtl(authenticationPublicKey) + ) { + return encodeResponse("400", "", "Identity not authenticated"); + } + + let vCardImageClaimValue; + + const vCardImageClaimName = "vCardImage"; + const defaultTagName = "notag"; + + const vCardClaimResponse = await executeRestfulFunction( + "private", + window.viamApi, + window.viamApi.entityGetClaim, + null, + vCardImageClaimName, + defaultTagName, + passportUUID + ); + + // You may not have vCard image claim, but backend will still return blank image from passportGetVCardImage + + // if (vCardClaimResponse.code !== "200") { + // return encodeResponse("400", "", vCardClaimResponse.status); + // } + + if (vCardClaimResponse.code === "200") { + vCardImageClaimValue = vCardClaimResponse.data; + } + + if ( + vCardImageClaimValue && + "state" in vCardImageClaimValue + ) { + return encodeResponse("200", vCardImageClaimValue.state, "OK"); + } + + return encodeResponse("200", "enabled", "OK"); + }, + /** + * + * @param passportUUID + * @param documentUUID + * @param documentContentType + * @param signatureData - + * @returns {Promise<{code: *, data: *, status: *}>} + * +// Image position in pixels +message Position { + int32 left = 1; // x + int32 top = 2; // y +} + + // Image size in pixels + message Size { + uint32 width = 1; + uint32 height = 2; +} + + // Image size in pixels + message Bounds { + int32 left = 1; // x + int32 top = 2; // y + uint32 width = 3; + uint32 height = 4; +} +message SignatureData { + ImageData signatureImageData = 1; + Bounds signatureBounds = 2; + uint32 pageNumber = 3; + Size pageSize = 4; +} + * + */ signDocumentJava: async ( passportUUID, documentUUID, - documentContentType + documentContentType, + signatureData = null, + qrCodeUrl = null ) => { const authenticationPublicKey = localStorage.getItem( "authenticatedIdentity" @@ -1384,6 +1479,80 @@ const connection = Penpal.connectToParent({ return encodeResponse("400", "", "Identity not authenticated"); } + + // Get vCard and QR Code Coordinates + + let vCardImageData; + let vCardImageClaimValue; + + let qrCodeImageData; + let qrCodeCoordinates = {fromL: -1, fromR: -1, toL: -1, toR: -1}; + + if (signatureData) { + const vCardImageClaimName = "vCardImage"; + const defaultTagName = "notag"; + + const vCardClaimResponse = await executeRestfulFunction( + "private", + window.viamApi, + window.viamApi.entityGetClaim, + null, + vCardImageClaimName, + defaultTagName, + passportUUID + ); + // if (vCardClaimResponse.code !== "200") { + // return encodeResponse("400", "", vCardClaimResponse.status); + // } + + if (vCardClaimResponse.code === "200") { + vCardImageClaimValue = vCardClaimResponse.data; + } + + if ( + vCardImageClaimValue && + "state" in vCardImageClaimValue && + vCardImageClaimValue.state === "disabled" + ) { + vCardImageData = TRANSPARENT_PIXEL; + } else { + const vCardImageResponse = await executeRestfulFunction( + "private", + window.viamApi, + window.viamApi.passportGetVCardImage, + null, + passportUUID + ); + + if (vCardImageResponse.code !== "200") { + return encodeResponse("400", "", vCardImageResponse.status); + } + vCardImageData = new ImageData(vCardImageResponse.data.Image); + if (vCardImageData.contentType !== "image/png") { + return encodeResponse( + "400", + "", + "Content type of vCard must be 'image/png'" + ); + } + + if (qrCodeUrl) { + qrCodeCoordinates = vCardImageResponse.data.QRCodeCoordinates; + const qrCodeBase64Content = await generateQrCode(qrCodeUrl); + qrCodeImageData = new ImageData({ + contentType: "image/png", + content: qrCodeBase64Content + }); + } + } + + // Fill signature data onject + + signatureData.signatureImageData = vCardImageData; + } + + // Generate certificate chain + const certResponse = await getCertificateForPassport(passportUUID, true); if (certResponse.code !== "200") { @@ -1415,6 +1584,8 @@ const connection = Penpal.connectToParent({ passportChain.reverse(); + // eventually convert document + const pdfContentType = "application/pdf"; if (documentContentType !== pdfContentType) { @@ -1432,6 +1603,8 @@ const connection = Penpal.connectToParent({ } } + // Sign document + const signResponse = await executeRestfulFunction( "private", window.viamApi, @@ -1441,7 +1614,10 @@ const connection = Penpal.connectToParent({ passportChain, passportUUID, documentUUID, - pdfContentType + pdfContentType, + signatureData, + qrCodeImageData, + qrCodeCoordinates ); if (signResponse.code !== "200") { return encodeResponse("400", "", signResponse.status); @@ -1495,6 +1671,9 @@ const connection = Penpal.connectToParent({ let vCardImageData; let vCardImageClaimValue; + let qrCodeImageData; + let qrCodeCoordinates = {fromL: -1, fromR: -1, toL: -1, toR: -1}; + const vCardImageClaimName = "vCardImage"; const defaultTagName = "notag"; @@ -1515,19 +1694,12 @@ const connection = Penpal.connectToParent({ vCardImageClaimValue = vCardClaimResponse.data; } - let qrCodeImageData; - let qrCodeCoordinates = { fromL: -1, fromR: -1, toL: -1, toR: -1 }; - if ( vCardImageClaimValue && "state" in vCardImageClaimValue && vCardImageClaimValue.state === "disabled" ) { - vCardImageData = new ImageData({ - contentType: "image/png", - contentBase64: - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" //1x1px transparent pixel - }); + vCardImageData = TRANSPARENT_PIXEL; } else { const vCardImageResponse = await executeRestfulFunction( "private", @@ -1537,8 +1709,6 @@ const connection = Penpal.connectToParent({ passportUUID ); - console.log(vCardImageResponse); - if (vCardImageResponse.code !== "200") { return encodeResponse("400", "", vCardImageResponse.status); } @@ -1547,7 +1717,7 @@ const connection = Penpal.connectToParent({ return encodeResponse( "400", "", - "Content type of vCard mmust be 'image/png'" + "Content type of vCard must be 'image/png'" ); } @@ -1638,8 +1808,6 @@ const connection = Penpal.connectToParent({ passportChain.reverse(); - console.log(qrCodeImageData); - console.log(qrCodeCoordinates); const signVCardResponse = await executeRestfulFunction( "private",