Skip to content
Snippets Groups Projects

269 implement workflow for signing already uploaded document

6 files
+ 11195
99
Compare changes
  • Side-by-side
  • Inline
Files
6
@@ -16,6 +16,9 @@ import {
@@ -16,6 +16,9 @@ import {
decryptMessage,
decryptMessage,
encryptMessage, signEmail
encryptMessage, signEmail
} from '../utilities/signingUtilities';
} from '../utilities/signingUtilities';
 
import {
 
signPdf
 
} from '../utilities/pdfUtilities';
import CryptoData from '../CryptoData';
import CryptoData from '../CryptoData';
import Identity from '../Identity';
import Identity from '../Identity';
import {STATUS_DEVICE_REVOKED} from '../constants/statuses';
import {STATUS_DEVICE_REVOKED} from '../constants/statuses';
@@ -248,7 +251,23 @@ const handleIdentityLogin = (identity, uuid, token) => {
@@ -248,7 +251,23 @@ const handleIdentityLogin = (identity, uuid, token) => {
async function executeRestfulFunction(type, that, fn, config, ...args) {
async function executeRestfulFunction(type, that, fn, config, ...args) {
const { currentlyAuthenticatedIdentity, viamApi, currentlyLoadedIdentity } = window;
const { currentlyAuthenticatedIdentity, viamApi, currentlyLoadedIdentity } = window;
const response = await fn.apply(that, [config, ...args]);
let response;
 
try {
 
response = await fn.apply(that, [config, ...args]);
 
} catch (error) {
 
if (error.response) {
 
//Resposnse with status code != 2xx still has valid response
 
response = error.response;
 
} else {
 
//Connection error or similar
 
const data = {
 
"data": "",
 
"code": "999",
 
"status": error.message
 
};
 
return data;
 
}
 
}
const identity = currentlyAuthenticatedIdentity || currentlyLoadedIdentity;
const identity = currentlyAuthenticatedIdentity || currentlyLoadedIdentity;
const { code, status } = response.data;
const { code, status } = response.data;
@@ -272,8 +291,12 @@ async function executeRestfulFunction(type, that, fn, config, ...args) {
@@ -272,8 +291,12 @@ async function executeRestfulFunction(type, that, fn, config, ...args) {
const uuid = loginResponse.data.data["Uuid"];
const uuid = loginResponse.data.data["Uuid"];
const token = loginResponse.data.data["Session"];
const token = loginResponse.data.data["Session"];
handleIdentityLogin(identity, uuid, token);
handleIdentityLogin(identity, uuid, token);
const { data } = await fn.apply(that, [config, ...args]);
try {
return data;
response = await fn.apply(that, [config, ...args]);
 
} catch (error) {
 
response = error.response;
 
}
 
return response.data;
}
}
window.executeRestfulFunction = executeRestfulFunction;
window.executeRestfulFunction = executeRestfulFunction;
@@ -411,6 +434,60 @@ function getCertificateForPassport(passportUUID, internal) {
@@ -411,6 +434,60 @@ function getCertificateForPassport(passportUUID, internal) {
});
});
}
}
 
function stringToUtf8ByteArray(str) {
 
if (typeof str !== 'string') {
 
str = str.toString();
 
}
 
const res = Buffer.from(str, 'utf-8');
 
return res;
 
}
 
 
function utf8ByteArrayToString(ba) {
 
if (!Buffer.isBuffer(ba)) {
 
ba = Buffer.from(ba);
 
}
 
const res = ba.toString('utf-8');
 
return res;
 
}
 
 
function stringToUtf8Base64(str) {
 
if (!Buffer.isBuffer(str)) {
 
if (typeof str !== 'string') {
 
str = str.toString();
 
}
 
str = Buffer.from(str, 'utf-8');
 
}
 
const res = str.toString('base64');
 
return res;
 
}
 
 
function utf8Base64ToString(strBase64) {
 
if (!Buffer.isBuffer(strBase64)) {
 
if (typeof strBase64 !== 'string') {
 
strBase64 = strBase64.toString();
 
}
 
strBase64 = Buffer.from(strBase64, 'base64');
 
}
 
const res = strBase64.toString('utf-8');
 
return res;
 
}
 
 
function base64ToByteArray(strBase64) {
 
if (typeof strBase64 !== 'string') {
 
strBase64 = strBase64.toString();
 
}
 
const res = Buffer.from(strBase64, 'base64');
 
return res;
 
}
 
 
function byteArrayToBase64(ba) {
 
if (!Buffer.isBuffer(ba)) {
 
ba = Buffer.from(ba);
 
}
 
const res = ba.toString('base64');
 
return res;
 
}
 
const connection = Penpal.connectToParent({
const connection = Penpal.connectToParent({
// Methods child is exposing to parent
// Methods child is exposing to parent
methods: {
methods: {
@@ -929,6 +1006,75 @@ const connection = Penpal.connectToParent({
@@ -929,6 +1006,75 @@ const connection = Penpal.connectToParent({
return encodeResponse("200", response.data, "Email signed");
return encodeResponse("200", response.data, "Email signed");
},
},
 
signDocument: async (passportUUID, documentUUID, documentContentType) => {
 
 
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
 
 
if (
 
!authenticationPublicKey ||
 
!window.loadedIdentities[authenticationPublicKey] ||
 
!extendPinCodeTtl(authenticationPublicKey)
 
) {
 
return encodeResponse("400", "", "Identity not authenticated");
 
}
 
 
const certResponse = await getCertificateForPassport(passportUUID, true);
 
 
if (certResponse.code !== "200") {
 
return encodeResponse("400", "", certResponse.status);
 
}
 
 
const {
 
x509Certificate: passportCertificate,
 
privateKey: passportPrivateKey,
 
chain: passportChain
 
} = certResponse.data;
 
 
const keys =
 
await createOneTimePassportCertificate(
 
makeid() + "-" + passportUUID, null, passportPrivateKey, passportCertificate);
 
 
const { privateKeyPEM: privateKeyOneTime, certificatePEM: certificateOneTime } = keys;
 
 
passportChain.push(passportCertificate);
 
 
const pdfContentType = 'application/pdf';
 
 
if (documentContentType !== pdfContentType) {
 
const convResponse = await executeRestfulFunction(
 
"private", window.viamApi, window.viamApi.documentConvertDocumentByUUID, null, documentUUID, documentContentType, pdfContentType);
 
if (convResponse.code !== "200") {
 
return encodeResponse("400", "", convResponse.status);
 
}
 
}
 
 
const downloadResponse = await executeRestfulFunction(
 
"private", window.viamApi, window.viamApi.documentGetDocumentByUUID, null, documentUUID, pdfContentType);
 
 
if (downloadResponse.code !== "200") {
 
return encodeResponse("400", "", downloadResponse.status);
 
}
 
 
const pdfRaw = base64ToByteArray(downloadResponse.data);
 
 
const signedPdf = await signPdf(pdfRaw, certificateOneTime, passportChain, privateKeyOneTime);
 
 
const signedPdfB64 = byteArrayToBase64(signedPdf);
 
 
const uploadResponse = await executeRestfulFunction(
 
"private", window.viamApi, window.viamApi.documentPutDocumentByUUID, null, documentUUID, pdfContentType, signedPdfB64);
 
if (uploadResponse.code !== "200") {
 
return encodeResponse("400", "", uploadResponse.status);
 
}
 
 
const signResponse = await executeRestfulFunction(
 
"private", window.viamApi, window.viamApi.documentSignDocumentByUUID, null, passportUUID, documentUUID, pdfContentType);
 
if (signResponse.code !== "200") {
 
return encodeResponse("400", "", signResponse.status);
 
}
 
 
return encodeResponse("200", "", "Document signed");
 
},
documentCreateDocument: async (path, passportUUID, contenttype) => {
documentCreateDocument: async (path, passportUUID, contenttype) => {
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
const authenticationPublicKey = localStorage.getItem("authenticatedIdentity");
if (
if (
@@ -1052,64 +1198,34 @@ const connection = Penpal.connectToParent({
@@ -1052,64 +1198,34 @@ const connection = Penpal.connectToParent({
);
);
},
},
stringToUtf8ByteArray(str) {
stringToUtf8ByteArray(str) {
if (typeof str !== 'string') {
str = str.toString()
}
let res = Buffer.from(str,'utf-8');
return new Penpal.Promise(result => {
return new Penpal.Promise(result => {
result(res)
result(stringToUtf8ByteArray(str));
})
});
},
},
utf8ByteArrayToString(ba) {
utf8ByteArrayToString(ba) {
if (!Buffer.isBuffer(ba)) {
ba = Buffer.from(ba)
}
let res = ba.toString('utf-8');
return new Penpal.Promise(result => {
return new Penpal.Promise(result => {
result(res)
result(utf8ByteArrayToString(ba));
})
});
},
},
stringToUtf8Base64(str) {
stringToUtf8Base64(str) {
if (!Buffer.isBuffer(str)) {
if (typeof str !== 'string') {
str = str.toString()
}
str = Buffer.from(str, 'utf-8')
}
let res = str.toString('base64');
return new Penpal.Promise(result => {
return new Penpal.Promise(result => {
result(res)
result(stringToUtf8Base64(str));
})
});
},
},
utf8Base64ToString(strBase64) {
utf8Base64ToString(strBase64) {
if (!Buffer.isBuffer(strBase64)) {
if (typeof strBase64 !== 'string') {
strBase64 = strBase64.toString()
}
strBase64 = Buffer.from(strBase64, 'base64')
}
let res = strBase64.toString('utf-8');
return new Penpal.Promise(result => {
return new Penpal.Promise(result => {
result(res)
result(utf8Base64ToString(strBase64));
})
});
},
},
base64ToByteArray(strBase64) {
base64ToByteArray(strBase64) {
if (typeof strBase64 !== 'string') {
strBase64 = strBase64.toString()
}
let res = Buffer.from(strBase64, 'base64');
return new Penpal.Promise(result => {
return new Penpal.Promise(result => {
result(res)
result(base64ToByteArray(strBase64));
})
});
},
},
byteArrayToBase64(ba) {
byteArrayToBase64(ba) {
if (!Buffer.isBuffer(ba)) {
ba = Buffer.from(ba)
}
let res = ba.toString('base64');
return new Penpal.Promise(result => {
return new Penpal.Promise(result => {
result(res)
result(byteArrayToBase64(ba));
})
});
},
},
// Collabora APIs
// Collabora APIs
Loading