diff --git a/.env.production b/.env.production index 8cabc5a..fbb7f5d 100644 --- a/.env.production +++ b/.env.production @@ -1,2 +1,6 @@ CREDENTIALS_ENABLED = 1 +CREDENTIALS_PATH = ~/.certbot/config/live/algorithm-visualizer.org +CREDENTIALS_CA = fullchain.pem +CREDENTIALS_KEY = privkey.pem +CREDENTIALS_CERT = cert.pem WEBHOOK_ENABLED = 1 diff --git a/certbot.ini b/certbot.ini new file mode 100644 index 0000000..fa5060a --- /dev/null +++ b/certbot.ini @@ -0,0 +1,7 @@ +config-dir = ~/.certbot/config +work-dir = ~/.certbot/work +logs-dir = ~/.certbot/logs +email = jason.park@gatech.edu +authenticator = webroot +webroot-path = ~/server/public/frontend-built +domains = algorithm-visualizer.org diff --git a/src/config/environments.ts b/src/config/environments.ts index 1824314..088dca7 100644 --- a/src/config/environments.ts +++ b/src/config/environments.ts @@ -1,15 +1,11 @@ import fs from 'fs'; import { ServerOptions } from 'https'; import path from 'path'; +import { spawn } from 'child_process'; +import { rootDir } from 'config/paths'; require('dotenv-flow').config(); -declare var process: { - env: { - [key: string]: string, - } -}; - const { NODE_ENV, @@ -30,7 +26,9 @@ const { AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, -} = process.env; +} = process.env as { + [key: string]: string, +}; const isEnabled = (v: string) => v === '1'; @@ -67,12 +65,30 @@ export const webhookOptions = isEnabled(WEBHOOK_ENABLED) ? { secret: WEBHOOK_SECRET, } : undefined; -const readCredentials = (file: string) => fs.readFileSync(path.resolve(CREDENTIALS_PATH, file)); -export const credentials: ServerOptions | undefined = isEnabled(CREDENTIALS_ENABLED) ? { - ca: readCredentials(CREDENTIALS_CA), - key: readCredentials(CREDENTIALS_KEY), - cert: readCredentials(CREDENTIALS_CERT), -} : undefined; +export let credentials: ServerOptions | undefined; +if (isEnabled(CREDENTIALS_ENABLED)) { + if (fs.existsSync(CREDENTIALS_PATH)) { + const readCredentials = (file: string) => fs.readFileSync(path.resolve(CREDENTIALS_PATH, file)); + credentials = { + ca: readCredentials(CREDENTIALS_CA), + key: readCredentials(CREDENTIALS_KEY), + cert: readCredentials(CREDENTIALS_CERT), + }; + } else { + const certbotIniPath = path.resolve(rootDir, 'certbot.ini'); + const childProcess = spawn('certbot', ['certonly', '--non-interactive', '--agree-tos', '--config', certbotIniPath]); + childProcess.stdout.pipe(process.stdout); + childProcess.stderr.pipe(process.stderr); + childProcess.on('error', console.error); + childProcess.on('exit', code => { + if (code === 0) { + process.exit(0); + } else { + console.error(new Error(`certbot failed with exit code ${code}.`)); + } + }); + } +} export const githubClientId = GITHUB_CLIENT_ID; export const githubClientSecret = GITHUB_CLIENT_SECRET;