All files / lib/helpers certsUtils.js

96.96% Statements 32/33
83.33% Branches 5/6
100% Functions 14/14
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105                4x       30x 52x           4x       24x 30x             4x       24x 30x         24x         4x 24x           4x       14x 18x           4x       14x 14x         4x 24x 24x 24x 24x         14x 14x 14x           14x 14x     24x           12x      
/**
 * @import forge from "node-forge";
 */
 
/**
 * @param {forge.pki.Certificate} cert
 */
const issued =
	(cert) =>
	/**
	 * @param {forge.pki.Certificate} anotherCert
	 */
	(anotherCert) =>
		cert !== anotherCert && anotherCert.issued(cert);
 
/**
 * @param {readonly forge.pki.Certificate[]} certsArray
 */
const getIssuer =
	(certsArray) =>
	/**
	 * @param {forge.pki.Certificate} cert
	 */
	(cert) =>
		certsArray.find(issued(cert));
 
/**
 * @template T
 * @param {(x: T)=>unknown}f
 */
const inverse =
	(f) =>
	/**
	 * @param {T} x
	 */
	(x) =>
		!f(x);
 
/**
 * @param {readonly forge.pki.Certificate[]} certsArray
 */
const hasNoIssuer = (certsArray) => inverse(getIssuer(certsArray));
 
/**
 * @param {readonly forge.pki.Certificate[]} certsArray
 */
const getChainRootCertificateIdx = (certsArray) =>
	certsArray.findIndex(hasNoIssuer(certsArray));
 
/**
 * @param {forge.pki.Certificate} cert
 */
const isIssuedBy =
	(cert) =>
	/**
	 * @param {forge.pki.Certificate} anotherCert
	 */
	(anotherCert) =>
		cert !== anotherCert && cert.issued(anotherCert);
 
/**
 * @param {readonly forge.pki.Certificate[]} certsArray
 */
const getChildIdx =
	(certsArray) =>
	/**
	 * @param {forge.pki.Certificate} parent
	 */
	(parent) =>
		certsArray.findIndex(isIssuedBy(parent));
 
/**
 * @param {readonly forge.pki.Certificate[]} certs
 */
const sortCertificateChain = (certs) => {
	const certsArray = Array.from(certs);
	const rootCertIndex = getChainRootCertificateIdx(certsArray);
	const certificateChain = certsArray.splice(rootCertIndex, 1);
	while (certsArray.length) {
		/**
		 * @type {forge.pki.Certificate}
		 */
		// @ts-expect-error not-null
		const lastCert = certificateChain[0];
		const childCertIdx = getChildIdx(certsArray)(lastCert);
		Iif (childCertIdx === -1) certsArray.splice(childCertIdx, 1);
		else {
			/**
			 * @type {[forge.pki.Certificate]}
			 */
			// @ts-expect-error not-null
			const [childCert] = certsArray.splice(childCertIdx, 1);
			certificateChain.unshift(childCert);
		}
	}
	return certificateChain;
};
 
/**
 * @param {readonly forge.pki.Certificate[]} certs
 */
const getClientCertificate = (certs) => sortCertificateChain(certs)[0];
 
export { sortCertificateChain, getClientCertificate };