Skip to content
Snippets Groups Projects
Commit d4f976f6 authored by Gospodin Bodurov's avatar Gospodin Bodurov
Browse files

Merge branch '53-optimize-transmission-of-vcard-parts' into 'master'

calc sha256 hash of parts on the client side

Closes #53

See merge request !81
parents 07a52994 1ba0b9ec
Branches
Tags
1 merge request!81calc sha256 hash of parts on the client side
......@@ -1539,7 +1539,7 @@ const connection = Penpal.connectToParent({
console.log("Text body is not passed to signVCard, its value is ", {text: textBody});
}
const count = prepareVCardParts(parts);
const count = await prepareVCardParts(parts);
if (count.textParts === 0) {
return encodeResponse("400", "", "No text parts passed to signVCard");
}
......
......@@ -17,8 +17,10 @@ import {
} from "./signingUtilities";
import {
byteArrayToBase64,
stringToUtf8Base64
stringToUtf8Base64,
stringToUtf8ByteArray
} from "./stringUtilities";
import {getCrypto} from "pkijs";
export const SIGNATURE_CONTENT_TYPE = "application/pkcs7-signature";
export const DEFAULT_ATTACHMENT_NAME = "attachment";
......@@ -150,14 +152,52 @@ const capitalizeFirstLetter = (s) => {
return s.charAt(0).toUpperCase() + s.slice(1);
};
export function prepareVCardParts(parts) {
if (!parts) {
return;
async function sha256(array) {
const cryptoLib = getCrypto();
const digestTmpBuf = await cryptoLib.digest({ name: "SHA-256" }, array);
const digestTmpArray = new Uint8Array(digestTmpBuf);
return digestTmpArray;
}
async function hashBody(part) {
const contentType = part.headers["Content-Type"];
const origContentType = part.headers["Original-Content-Type"];
if (!origContentType &&
!part.headers["Content-Type"].startsWith("application/hash") &&
!part.headers["Content-Type"].startsWith("text/plain") &&
!part.headers["Content-Type"].startsWith("text/html")) {
if (part.body) {
if (typeof part.body === "string") {
part.body = stringToUtf8ByteArray(part.body);
}
if (part.body instanceof ArrayBuffer) {
part.body = byteArrayToBase64(new Uint8Array(part.body));
}
if (!(part.body instanceof Uint8Array)) {
throw new Error('part body is neither string, nor Uint8Array, nor ArrayBuffer'); // should not happen
}
if (contentType) {
part.headers["Original-Content-Type"] = contentType;
}
part.headers["Content-Type"] = "application/hash; algorithm=SHA-256";
part.body = await sha256(part.body);
}
}
}
export async function prepareVCardParts(parts) {
const count = {
textParts: 0,
htmlParts: 0
};
if (!parts) {
return count;
}
for (const part of parts) {
if (!part.headers) {
part.headers = {
......@@ -169,17 +209,18 @@ export function prepareVCardParts(parts) {
capitalizedHeaders[capitalizeHeaderName(key)] = part.headers[key];
}
part.headers = capitalizedHeaders;
try {
if (!part.headers["Content-Type"]) {
part.headers["Content-Type"] = "application/octet-stream";
} else {
if (part.headers["Content-Type"].startsWith("text/plain")) {
count.textParts++;
} else if (part.headers["Content-Type"].startsWith("text/html")) {
count.htmlParts++;
}
} catch (ignore) {
//ignore
}
}
if (part.body) {
await hashBody(part);
if (typeof part.body === "string") {
part.body = stringToUtf8Base64(part.body);
} else
......@@ -193,7 +234,7 @@ export function prepareVCardParts(parts) {
}
}
if (part.parts) {
const subcount = prepareVCardParts(part.parts);
const subcount = await prepareVCardParts(part.parts);
count.textParts += subcount.textParts;
count.htmlParts += subcount.htmlParts;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment