UNPKG

generate-certs

Version:

🗝️ Effortless HTTPS Certificate Generation for Local Development

1 lines 7.01 kB
{"version":3,"sources":["../src/generate.ts","../src/index.ts"],"names":["fs","path"],"mappings":"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","file":"index.mjs","sourcesContent":["import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport forge from \"node-forge\";\r\n\r\nexport function $generateCerts(certificatesPath: string) {\r\n if (fs.existsSync(certificatesPath)) fs.rmSync(certificatesPath, { recursive: true });\r\n\r\n fs.mkdirSync(certificatesPath, { recursive: true });\r\n\r\n const keys = forge.pki.rsa.generateKeyPair(2048);\r\n const privateKey = forge.pki.privateKeyToPem(keys.privateKey);\r\n fs.writeFileSync(path.join(certificatesPath, \"key.pem\"), privateKey);\r\n\r\n const cert = forge.pki.createCertificate();\r\n cert.publicKey = keys.publicKey;\r\n cert.serialNumber = \"01\";\r\n cert.validity.notBefore = new Date();\r\n cert.validity.notAfter = new Date();\r\n cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);\r\n\r\n const attrs = [{ name: \"commonName\", value: \"localhost\" }];\r\n\r\n cert.setSubject(attrs);\r\n cert.setIssuer(attrs);\r\n\r\n cert.sign(keys.privateKey, forge.md.sha256.create());\r\n\r\n const certPem = forge.pki.certificateToPem(cert);\r\n fs.writeFileSync(path.join(certificatesPath, \"cert.pem\"), certPem);\r\n}\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { $generateCerts } from \"./generate\";\r\n\r\n/** Options for generating self-signed HTTPS certificates. */\r\nexport interface GenerateCertsOptions {\r\n /**\r\n * The absolute path to the directory where the certificate files will be stored or retrieved.\r\n * Must be a valid, writable directory path.\r\n */\r\n certsPath: string;\r\n /**\r\n * Whether to log the generation process to the console.\r\n * Defaults to true, which logs success messages.\r\n */\r\n activateLogs?: boolean;\r\n}\r\n\r\n/**\r\n * Generates or retrieves self-signed HTTPS certificates from the specified directory.\r\n *\r\n * If valid `key.pem` and `cert.pem` files already exist in the target path,\r\n * they will be reused. Otherwise, new certificates will be generated.\r\n * Examples are provided for various frameworks and shown in the documentation.\r\n *\r\n * @param options - Options to control the certificate generation behavior.\r\n * @returns An object containing the PEM-formatted `key` and `cert` strings.\r\n *\r\n * @throws Will throw an error if the path is invalid, inaccessible, or certificate generation fails.\r\n *\r\n * @example\r\n * ```ts\r\n * const certs = generateCerts({ certsPath: path.resolve(__dirname, 'certs') });\r\n *\r\n * // Express example:\r\n * https.createServer(certs, app);\r\n *\r\n * // NestJS example:\r\n * const app = await NestFactory.create(AppModule, { httpsOptions: certs });\r\n * ```\r\n */\r\nexport function generateCerts({ certsPath, activateLogs = true }: GenerateCertsOptions) {\r\n const certs = $checkForCerts({ certsPath, activateLogs });\r\n if (certs) return certs;\r\n try {\r\n $generateCerts(certsPath);\r\n if (activateLogs) {\r\n console.log(\"🔐 Certificates for HTTPS have been generated successfully!\");\r\n console.log(`🛑 Please visit the URL, click on 'Advanced' -> 'Proceed to localhost(unsafe)' to continue.`);\r\n }\r\n return { key: $readFile(certsPath, \"key.pem\"), cert: $readFile(certsPath, \"cert.pem\") };\r\n } catch (err) {\r\n throw new Error(`❌ Error generating certificates: ${err instanceof Error ? err.message : \"Unknown error\"}`);\r\n }\r\n}\r\n\r\nfunction $checkForCerts({ certsPath, activateLogs: log = true }: GenerateCertsOptions) {\r\n try {\r\n if ($isFileExists(certsPath, \"key.pem\") && $isFileExists(certsPath, \"cert.pem\")) {\r\n if (log) console.log(\"🔍 Found existing certificates for HTTPS.\");\r\n return { key: $readFile(certsPath, \"key.pem\"), cert: $readFile(certsPath, \"cert.pem\") };\r\n }\r\n } catch (err) {\r\n throw new Error(\r\n `❌ Error checking for existing certificates: ${err instanceof Error ? err.message : \"Unknown error\"}`,\r\n );\r\n }\r\n}\r\n\r\nexport function $isFileExists(dir: string, fileName: string) {\r\n return fs.existsSync(path.join(dir, fileName));\r\n}\r\n\r\nexport function $readFile(dir: string, fileName: string) {\r\n if (!$isFileExists(dir, fileName)) throw new Error(`\"${fileName}\" not found.`);\r\n return fs.readFileSync(path.join(dir, fileName), \"utf8\");\r\n}\r\n"]}