MCPcopy Index your code
hub / github.com/cameri/nostream / ensureNginxBootstrap

Function ensureNginxBootstrap

src/cli/commands/start.ts:15–69  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

13 /^([A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/
14
15const ensureNginxBootstrap = async (): Promise<void> => {
16 const relayDomain = process.env.RELAY_DOMAIN?.trim()
17 if (!relayDomain) {
18 throw new Error(
19 'RELAY_DOMAIN environment variable is required when using --nginx (example: RELAY_DOMAIN=relay.example.com).',
20 )
21 }
22
23 if (!FQDN_REGEX.test(relayDomain)) {
24 throw new Error('RELAY_DOMAIN must be a valid fully-qualified domain name when using --nginx.')
25 }
26
27 const certbotEmail = process.env.CERTBOT_EMAIL?.trim()
28 if (!certbotEmail) {
29 throw new Error(
30 'CERTBOT_EMAIL environment variable is required when using --nginx (example: CERTBOT_EMAIL=you@example.com).',
31 )
32 }
33
34 const nginxConfDir = getProjectPath('nginx', 'conf.d')
35 const nginxTemplate = join(nginxConfDir, 'nostream.conf.template')
36 const nginxConf = join(nginxConfDir, 'nostream.conf')
37
38 const templateContent = fs.readFileSync(nginxTemplate, 'utf-8')
39 const rendered = templateContent.replaceAll('${RELAY_DOMAIN}', relayDomain)
40 fs.writeFileSync(nginxConf, rendered, { encoding: 'utf-8' })
41
42 const sslCertDir = getProjectPath('nginx', 'ssl', 'live', relayDomain)
43 const fullchainPath = join(sslCertDir, 'fullchain.pem')
44 const privkeyPath = join(sslCertDir, 'privkey.pem')
45
46 if (!fs.existsSync(fullchainPath) || !fs.existsSync(privkeyPath)) {
47 fs.mkdirSync(sslCertDir, { recursive: true })
48
49 const code = await runCommand('openssl', [
50 'req',
51 '-x509',
52 '-nodes',
53 '-newkey',
54 'rsa:2048',
55 '-days',
56 '1',
57 '-keyout',
58 privkeyPath,
59 '-out',
60 fullchainPath,
61 '-subj',
62 `/CN=${relayDomain}`,
63 ])
64
65 if (code !== 0) {
66 throw new Error('Failed to generate self-signed SSL certificate. Ensure openssl is installed and retry.')
67 }
68 }
69}
70
71export const runStart = async (options: StartOptions, passthrough: string[]): Promise<number> => {
72 ensureNotRoot()

Callers 1

runStartFunction · 0.85

Calls 2

getProjectPathFunction · 0.90
runCommandFunction · 0.90

Tested by

no test coverage detected