198 lines
5.0 KiB
TypeScript
Raw Normal View History

import { EndpointType } from "$lib/server/enums/endpoints"
import { httpVersion, proxyProtocol, secureProtocol, type NginxProtocol } from "$lib/server/enums/protocols"
import { validatePort } from "$lib/server/utils/ports-utils"
import type { Stats } from "fs"
import type { FSHeader, IEndpointFS } from "./endpoints"
import { createHeader } from "../utils"
export class SSLTerminationFS implements IEndpointFS {
private static __type = EndpointType.SSL_TERMINATION
public get type() {
return SSLTerminationFS.__type
}
public name: string
public stats: Stats
public path: string
public hash: string
public sslPort: number
public clearPort: number
public servicePort: number
public serviceEndpoint: string
public protocol: NginxProtocol
public certificateURI: string
public privateKeyURI: string
constructor(
name: string,
stats: Stats,
path: string,
hash: string,
sslPort: number,
clearPort: number,
servicePort: number,
serviceEndpoint: string,
protocol: NginxProtocol,
certificateURI: string,
privateKeyURI: string
) {
validatePort(sslPort)
validatePort(clearPort)
validatePort(servicePort)
this.name = name
this.stats = stats
this.path = path
this.hash = hash
this.sslPort = sslPort
this.clearPort = clearPort
this.servicePort = servicePort
this.serviceEndpoint = serviceEndpoint
this.protocol = protocol
this.certificateURI = certificateURI
this.privateKeyURI = privateKeyURI
}
toConf(): string {
const HEADER = this.createHeader()
const SSL_SERVER = this.createSSLServer()
const CLEAR_SERVER = this.createClearServer()
const CONF = HEADER + SSL_SERVER + CLEAR_SERVER
return CONF
}
ports(): number[]{
return [
this.sslPort,
this.clearPort
]
}
public static parseConf(fsHeader: FSHeader, conf: string) : SSLTerminationFS {
// TODO: parse header
}
private createHeader() {
return createHeader(
this,
[
{
key: "NAME",
value: this.name
},
{
key: "PROTOCOL",
value: this.protocol
},
{
key: "SSL_PORT",
value: this.sslPort
},
{
key: "CLEAR_PORT",
value: this.clearPort
},
{
key: "SERVICE_PORT",
value: this.servicePort
},
{
key: "SERVICE_ENDPOINT",
value: this.serviceEndpoint
},
{
key: "CERTIFICATE_PATH",
value: this.certificateURI
},
{
key: "KEY_PATH",
value: this.privateKeyURI
}
]
)
}
// UGLY: refactor into a flexible method
private createSSLServer() {
const CLEAR_PROTOCOL = `${this.protocol}`
const HTTP_VERSION = httpVersion(this.protocol)
const PROXY_OPTION = proxyProtocol(this.protocol)
// UGLY: put to constants
let conf = [
"server {\n",
"\tmore_clear_headers Server;\n",
`\tlisten ${this.sslPort};`
]
if (HTTP_VERSION !== 1) {
conf.push(
`\thttp${HTTP_VERSION} on;`
)
}
// TODO: check if we should support less protocols
conf.push(
"\n",
"\tlocation / {",
`\t\t${PROXY_OPTION} ${CLEAR_PROTOCOL}://127.0.0.1:${this.clearPort};`,
"\t}",
"\n",
`ssl_certificate ${this.certificateURI};`,
`ssl_certificate_key ${this.privateKeyURI};`,
"\tssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;",
"\n",
"}"
)
return conf.join("\n")
}
private createClearServer() {
const SSL_PROTOCOL = secureProtocol(this.protocol)
const HTTP_VERSION = httpVersion(this.protocol)
const PROXY_OPTION = proxyProtocol(this.protocol)
// UGLY: put to constants
let conf = [
"server {\n",
"\tmore_clear_headers Server;\n",
`\tlisten ${this.clearPort};`
]
if (HTTP_VERSION !== 1) {
conf.push(
`\thttp${HTTP_VERSION} on;`
)
}
// TODO: check if we should support less protocols
conf.push(
"\n",
"\tlocation / {",
`\t\t${PROXY_OPTION} ${SSL_PROTOCOL}://${this.serviceEndpoint}:${this.servicePort};`,
"\t}",
"\n",
"}"
)
return conf.join("\n")
}
}