Skip to content

Commit

Permalink
feat: allow for https boolean
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbbreuer committed Nov 15, 2024
1 parent a758d40 commit 6153960
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
25 changes: 25 additions & 0 deletions src/https.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
import type { TlsConfig } from '@stacksjs/tlsx'
import os from 'node:os'
import path from 'node:path'
import { log } from '@stacksjs/cli'
import { addCertToSystemTrustStoreAndSaveCert, createRootCA, generateCert } from '@stacksjs/tlsx'
import { config } from './config'

export const defaultHttpsConfig: TlsConfig = {
domain: 'stacks.localhost',
hostCertCN: 'stacks.localhost',
caCertPath: path.join(os.homedir(), '.stacks', 'ssl', `stacks.localhost.ca.crt`),
certPath: path.join(os.homedir(), '.stacks', 'ssl', `stacks.localhost.crt`),
keyPath: path.join(os.homedir(), '.stacks', 'ssl', `stacks.localhost.crt.key`),
altNameIPs: ['127.0.0.1'],
altNameURIs: ['localhost'],
organizationName: 'stacksjs.org',
countryName: 'US',
stateName: 'California',
localityName: 'Playa Vista',
commonName: 'stacks.localhost',
validityDays: 180,
verbose: false,
}

export async function generateCertificate(domain?: string): Promise<void> {
if (config.https === true)
config.https = defaultHttpsConfig
else if (config.https === false)
return

domain = domain ?? config.https.altNameURIs[0]

log.info(`Generating a self-signed SSL certificate for: ${domain}`)
Expand Down
41 changes: 35 additions & 6 deletions src/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import * as fs from 'node:fs'
import * as http from 'node:http'
import * as https from 'node:https'
import * as net from 'node:net'
import os from 'node:os'
import path from 'node:path'
import process from 'node:process'
import { bold, dim, green, log } from '@stacksjs/cli'
import { version } from '../package.json'
import { config } from './config'
import { generateCertificate } from './https'
import { defaultHttpsConfig, generateCertificate } from './https'
import { debugLog } from './utils'

// Keep track of all running servers for cleanup
Expand Down Expand Up @@ -59,6 +61,28 @@ process.on('uncaughtException', (err) => {
async function loadSSLConfig(options: ReverseProxyOption): Promise<SSLConfig | null> {
debugLog('ssl', 'Loading SSL configuration', options.verbose)

if (options.https === true) {
options.https = {
domain: 'stacks.localhost',
hostCertCN: 'stacks.localhost',
caCertPath: path.join(os.homedir(), '.stacks', 'ssl', `stacks.localhost.ca.crt`),
certPath: path.join(os.homedir(), '.stacks', 'ssl', `stacks.localhost.crt`),
keyPath: path.join(os.homedir(), '.stacks', 'ssl', `stacks.localhost.crt.key`),
altNameIPs: ['127.0.0.1'],
altNameURIs: ['localhost'],
organizationName: 'stacksjs.org',
countryName: 'US',
stateName: 'California',
localityName: 'Playa Vista',
commonName: 'stacks.localhost',
validityDays: 180,
verbose: false,
}
}
else if (options.https === false) {
return null
}

// Early return for non-SSL configuration
if (!options.https?.keyPath && !options.https?.certPath) {
debugLog('ssl', 'No SSL configuration provided', options.verbose)
Expand Down Expand Up @@ -200,10 +224,16 @@ export async function startServer(options?: ReverseProxyOption): Promise<void> {

// Check if HTTPS is configured and set SSL paths
if (config.https) {
if (config.https === true)
config.https = defaultHttpsConfig

const domain = config.https.altNameURIs?.[0] || new URL(options.to).hostname
options.keyPath = config.https.keyPath || `/Users/${process.env.USER}/.stacks/ssl/${domain}.crt.key`
options.certPath = config.https.certPath || `/Users/${process.env.USER}/.stacks/ssl/${domain}.crt`
debugLog('server', `HTTPS enabled, using cert paths: ${options.keyPath}, ${options.certPath}`, options.verbose)

if (typeof options.https !== 'boolean' && options.https) {
options.https.keyPath = config.https.keyPath || path.join(os.homedir(), '.stacks', 'ssl', `${domain}.crt.key`)
options.https.certPath = config.https.certPath || path.join(os.homedir(), '.stacks', 'ssl', `${domain}.crt`)
debugLog('server', `HTTPS enabled, using cert paths: ${options.https.keyPath}, ${options.https.certPath}`, options.verbose)
}
}

const fromUrl = new URL(options.from.startsWith('http') ? options.from : `http://${options.from}`)
Expand Down Expand Up @@ -441,8 +471,7 @@ export function startProxy(options?: ReverseProxyOption): void {
debugLog('proxy', `Starting proxy with options: ${JSON.stringify({
from: finalOptions.from,
to: finalOptions.to,
keyPath: finalOptions.https.keyPath,
certPath: finalOptions.https.certPath,
https: finalOptions.https,
})}`, finalOptions.verbose)

startServer(finalOptions).catch((err) => {
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { TlsConfig } from '@stacksjs/tlsx'
export interface ReverseProxyConfig {
from: string // localhost:5173
to: string // stacks.localhost
https: TlsConfig
https: boolean | TlsConfig
verbose: boolean
}

Expand Down

0 comments on commit 6153960

Please sign in to comment.