(hostname: string)
| 87 | } |
| 88 | |
| 89 | export const generateCertificate = async (hostname: string): Promise<{ cert: string; certKey: string }> => { |
| 90 | const certPath = path.join(paths.data, `${hostname.replace(/\./g, "_")}.crt`) |
| 91 | const certKeyPath = path.join(paths.data, `${hostname.replace(/\./g, "_")}.key`) |
| 92 | |
| 93 | // Try generating the certificates if we can't access them (which probably |
| 94 | // means they don't exist). |
| 95 | try { |
| 96 | await Promise.all([fs.access(certPath), fs.access(certKeyPath)]) |
| 97 | } catch (error) { |
| 98 | // Require on demand so openssl isn't required if you aren't going to |
| 99 | // generate certificates. |
| 100 | const pem = require("pem") as typeof import("pem") |
| 101 | const certs = await new Promise<import("pem").CertificateCreationResult>((resolve, reject): void => { |
| 102 | pem.createCertificate( |
| 103 | { |
| 104 | selfSigned: true, |
| 105 | commonName: hostname, |
| 106 | config: ` |
| 107 | [req] |
| 108 | req_extensions = v3_req |
| 109 | |
| 110 | [ v3_req ] |
| 111 | basicConstraints = CA:true |
| 112 | extendedKeyUsage = serverAuth |
| 113 | subjectAltName = @alt_names |
| 114 | |
| 115 | [alt_names] |
| 116 | DNS.1 = ${hostname} |
| 117 | `, |
| 118 | }, |
| 119 | (error, result) => { |
| 120 | return error ? reject(error) : resolve(result) |
| 121 | }, |
| 122 | ) |
| 123 | }) |
| 124 | await fs.mkdir(paths.data, { recursive: true }) |
| 125 | await Promise.all([fs.writeFile(certPath, certs.certificate), fs.writeFile(certKeyPath, certs.serviceKey)]) |
| 126 | } |
| 127 | |
| 128 | return { |
| 129 | cert: certPath, |
| 130 | certKey: certKeyPath, |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | export const generatePassword = async (length = 24): Promise<string> => { |
| 135 | const buffer = Buffer.alloc(Math.ceil(length / 2)) |
no test coverage detected