Skip to content

Commit

Permalink
docs: add JSDoc documentation to generate509 module
Browse files Browse the repository at this point in the history
- Add comprehensive JSDoc documentation to generate509.ts and generate509.spec.ts
- Document module purpose, interfaces, and function parameters
- Add detailed descriptions for certificate generation methods
- Include test suite documentation with test case descriptions
- Improve code readability with properly formatted parameter lists
- Remove unnecessary eslint-disable comment

Signed-off-by: Greg Osuri <[email protected]>
  • Loading branch information
gosuri committed Dec 10, 2024
1 parent 2e2741e commit c6d0d52
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 12 deletions.
14 changes: 13 additions & 1 deletion src/certificates/generate509/generate509.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { faker } from "@faker-js/faker";
/**
* @module generate509.spec
* Test suite for the X.509 certificate generation functionality
*/

import { faker } from "@faker-js/faker";
import { create } from "./generate509";

/**
* Test suite for the generate509 module
* @group Certificates
*/
describe("generate509", () => {
/**
* Tests the certificate generation functionality
* Verifies that the generated certificate components are in the correct PEM format
*/
it("should generate a CSR", async () => {
const address = `akash1${faker.string.alpha({ length: 38 })}`;
const cert = await create(address);
Expand Down
57 changes: 52 additions & 5 deletions src/certificates/generate509/generate509.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { arrayBufferToString, toBase64 } from "pvutils";
/**
* @module generate509
* Provides functionality to generate X.509 certificates for client authentication
*/

import { arrayBufferToString, toBase64 } from "pvutils";
import * as asn1js from "asn1js";

global.crypto = require("node:crypto");
Expand All @@ -12,17 +16,29 @@ const {
BasicConstraints,
Extension,
ExtKeyUsage
// eslint-disable-next-line @typescript-eslint/no-var-requires
} = require("pkijs/build");

Check failure on line 19 in src/certificates/generate509/generate509.ts

View workflow job for this annotation

GitHub Actions / Code Style / Lint

Require statement not part of import statement

const HASH_ALG = "SHA-256";
const SIGN_ALG = "ECDSA";

/**
* Interface representing the PEM-formatted certificate components
* @interface
*/
export interface pems {
/** The Certificate Signing Request (CSR) in PEM format */
csr: string;
/** The public key in PEM format */
publicKey: string;
/** The private key in PEM format */
privateKey: string;
}

/**
* Creates a new X.509 certificate for the given address
* @param {string} address - The address to create the certificate for
* @returns {Promise<pems>} Object containing the PEM-formatted certificate components
*/
export async function create(address: string): Promise<pems> {
// get crypto handler
const crypto = getCrypto();
Expand All @@ -48,7 +64,22 @@ export async function create(address: string): Promise<pems> {
};
}

async function createCSR(keyPair: { privateKey: string; publicKey: string }, hashAlg: string, { commonName }: { commonName: string }) {
/**
* Creates a Certificate Signing Request (CSR) with the given parameters
* @param {Object} keyPair - The public/private key pair
* @param {string} keyPair.privateKey - The private key
* @param {string} keyPair.publicKey - The public key
* @param {string} hashAlg - The hashing algorithm to use
* @param {Object} params - Certificate parameters
* @param {string} params.commonName - The common name for the certificate
* @returns {Promise<Certificate>} The generated certificate
* @private
*/
async function createCSR(
keyPair: { privateKey: string; publicKey: string },
hashAlg: string,
{ commonName }: { commonName: string }
) {
const cert = new Certificate();
cert.version = 2;

Expand Down Expand Up @@ -130,12 +161,28 @@ async function createCSR(keyPair: { privateKey: string; publicKey: string }, has
return cert;
}

// add line break every 64th character
/**
* Formats a PEM string by adding line breaks every 64 characters
* @param {string} pemString - The PEM string to format
* @returns {string} The formatted PEM string
* @private
*/
function formatPEM(pemString: string) {
return pemString.replace(/(.{64})/g, "$1\n");
}

function setValidityPeriod(cert: { notBefore: { value: Date }; notAfter: { value: Date } }, startDate: Date, durationInDays: number) {
/**
* Sets the validity period for a certificate
* @param {Object} cert - The certificate object
* @param {Date} startDate - The start date of the validity period
* @param {number} durationInDays - The duration in days for which the certificate should be valid
* @private
*/
function setValidityPeriod(
cert: { notBefore: { value: Date }; notAfter: { value: Date } },
startDate: Date,
durationInDays: number
) {
// Normalize to midnight
const start = new Date(startDate);
start.setHours(0);
Expand Down
44 changes: 38 additions & 6 deletions src/certificates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,21 @@ const jrpc = JsonRPC.connect_xhr("https://bridge.testnet.akash.network/akashnetw

export type { pems };

/**
* Deprecated type for CertificatePem with an additional `csr` field.
* @deprecated Use `CertificatePem` with `cert` instead of `csr`.
*/
export type CertificatePemDeprecated = CertificatePem & {
csr: string;
};

export async function broadcastCertificate(
pem: Pick<CertificatePem, "cert" | "publicKey">,
owner: string,
client: SigningStargateClient
): Promise<DeliverTxResponse>;
export async function broadcastCertificate(pem: pems, owner: string, client: SigningStargateClient): Promise<DeliverTxResponse>;
/**
* Broadcasts a certificate to the blockchain.
* @param pem - The certificate PEM object.
* @param owner - The owner of the certificate.
* @param client - The Stargate client used for signing and broadcasting.
* @returns A promise that resolves to the transaction response.
*/
export async function broadcastCertificate(
pem: Pick<CertificatePem, "cert" | "publicKey"> | pems,
owner: string,
Expand All @@ -46,6 +51,11 @@ export async function broadcastCertificate(
return await client.signAndBroadcast(owner, [message.message], message.fee);
}

/**
* Creates a new certificate for a given Bech32 address.
* @param bech32Address - The Bech32 address for which to create the certificate.
* @returns A promise that resolves to the deprecated certificate PEM object.
*/
export async function createCertificate(bech32Address: string): Promise<CertificatePemDeprecated> {
const pem = certificateManager.generatePEM(bech32Address);

Expand All @@ -58,6 +68,13 @@ export async function createCertificate(bech32Address: string): Promise<Certific
};
}

/**
* Revokes a certificate on the blockchain.
* @param owner - The owner of the certificate.
* @param serial - The serial number of the certificate to revoke.
* @param client - The Stargate client used for signing and broadcasting.
* @returns A promise that resolves to the transaction response.
*/
export async function revokeCertificate(owner: string, serial: string, client: SigningStargateClient) {
const message = createStarGateMessage(stargateMessages.MsgRevokeCertificate, {
id: {
Expand All @@ -69,6 +86,11 @@ export async function revokeCertificate(owner: string, serial: string, client: S
return await client.signAndBroadcast(owner, [message.message], message.fee);
}

/**
* Queries certificates based on a filter.
* @param filter - The filter criteria for querying certificates.
* @returns A promise that resolves to the query response.
*/
export async function queryCertificates(filter: CertificateFilter) {
const txBodyBytes = QueryCertificatesRequest.encode(
QueryCertificatesRequest.fromJSON({
Expand All @@ -90,6 +112,11 @@ export async function queryCertificates(filter: CertificateFilter) {
);
}

/**
* Converts a base64 string to a Uint8Array.
* @param base64 - The base64 encoded string.
* @returns A Uint8Array representation of the base64 string.
*/
function base64ToUInt(base64: string) {
if (typeof window !== "undefined") {
const binary_string = window.atob(base64);
Expand All @@ -104,6 +131,11 @@ function base64ToUInt(base64: string) {
return Buffer.from(base64, "base64");
}

/**
* Converts a Uint8Array buffer to a hexadecimal string.
* @param buffer - The buffer to convert.
* @returns A hexadecimal string representation of the buffer.
*/
function bufferToHex(buffer: Uint8Array) {
return [...new Uint8Array(buffer)].map(b => b.toString(16).padStart(2, "0")).join("");
}

0 comments on commit c6d0d52

Please sign in to comment.