Skip to content

Commit

Permalink
feat: Allow to use CA certificate file path for DB (#6985) (#6998)
Browse files Browse the repository at this point in the history
We'd like to get this out so you can get away with only defining a CA
certificate, the current iteration requires CA, CERT and KEY in order to
work. This PR splits it up and allows you to configure one.

---------

Co-authored-by: Egor Stronhin <6418221+egor-xyz@users.noreply.github.com>
  • Loading branch information
chriswk and egor-xyz committed May 8, 2024
1 parent 08c472c commit 60f637f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 63 deletions.
27 changes: 7 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,16 @@
"testTimeout": 10000,
"globalSetup": "./scripts/jest-setup.js",
"transform": {
"^.+\\.tsx?$": [
"@swc/jest"
]
"^.+\\.tsx?$": ["@swc/jest"]
},
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"testPathIgnorePatterns": [
"/dist/",
"/node_modules/",
"/frontend/"
],
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json"
"/frontend/",
"/website/"
],
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json"],
"coveragePathIgnorePatterns": [
"/node_modules/",
"/dist/",
Expand Down Expand Up @@ -236,14 +229,8 @@
"tough-cookie": "4.1.3"
},
"lint-staged": {
"*.{js,ts}": [
"biome check --apply --no-errors-on-unmatched"
],
"*.{jsx,tsx}": [
"biome check --apply --no-errors-on-unmatched"
],
"*.json": [
"biome format --write --no-errors-on-unmatched"
]
"*.{js,ts}": ["biome check --apply --no-errors-on-unmatched"],
"*.{jsx,tsx}": ["biome check --apply --no-errors-on-unmatched"],
"*.json": ["biome format --write --no-errors-on-unmatched"]
}
}
92 changes: 49 additions & 43 deletions src/lib/create-config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { parse } from 'pg-connection-string';
import merge from 'deepmerge';
import * as fs from 'fs';
import { readFileSync } from 'fs';
import { readFileSync, existsSync } from 'fs';
import {
type IAuthOption,
IAuthType,
Expand All @@ -21,6 +20,7 @@ import {
type IUnleashConfig,
type IUnleashOptions,
type IVersionOption,
type ISSLOption,
} from './types/option';
import { getDefaultLogProvider, LogLevel, validateLogProvider } from './logger';
import { defaultCustomAuthDenyAll } from './default-custom-auth-deny-all';
Expand Down Expand Up @@ -183,43 +183,51 @@ const dateHandlingCallback = (connection, callback) => {
});
};

const databaseSsl = () => {
const readAndAddOption = (
name: keyof ISSLOption,
value: string | undefined,
options: ISSLOption,
): ISSLOption =>
value != null
? { ...options, [name]: readFileSync(value).toString() }
: options;

const databaseSSL = (): IDBOption['ssl'] => {
if (process.env.DATABASE_SSL != null) {
return JSON.parse(process.env.DATABASE_SSL);
} else if (process.env.DATABASE_SSL_CA_CONFIG != null) {
return readFileSync(process.env.DATABASE_SSL_CA_CONFIG).toJSON();
} else if (
process.env.DATABASE_SSL_KEY_FILE != null &&
process.env.DATABASE_SSL_CERT_FILE != null
) {
const opts = {
rejectUnauthorized: parseEnvVarBoolean(
process.env.DATABASE_SSL_REJECT_UNAUTHORIZED,
true,
),
};
const key = readFileSync(process.env.DATABASE_SSL_KEY_FILE).toString();
const cert = readFileSync(
process.env.DATABASE_SSL_CERT_FILE,
).toString();
if (process.env.DATABASE_SSL_CA_FILE != null) {
return {
...opts,
ca: readFileSync(process.env.DATABASE_SSL_CA_FILE).toString(),
key,
cert,
};
} else {
return { ...opts, key, cert };
}
} else {
return {
rejectUnauthorized: parseEnvVarBoolean(
process.env.DATABASE_SSL_REJECT_UNAUTHORIZED,
false,
),
};
}

if (process.env.DATABASE_SSL_CA_CONFIG != null) {
return readFileSync(
process.env.DATABASE_SSL_CA_CONFIG,
).toString() as unknown as IDBOption['ssl'];
}

const rejectUnauthorizedDefault =
process.env.DATABASE_SSL_CA_FILE != null ||
process.env.DATABASE_SSL_CERT_FILE != null ||
process.env.DATABASE_SSL_KEY_FILE != null;

let options: ISSLOption = {
rejectUnauthorized: parseEnvVarBoolean(
process.env.DATABASE_SSL_REJECT_UNAUTHORIZED,
rejectUnauthorizedDefault,
),
};

options = readAndAddOption(
'key',
process.env.DATABASE_SSL_KEY_FILE,
options,
);
options = readAndAddOption(
'cert',
process.env.DATABASE_SSL_CERT_FILE,
options,
);
options = readAndAddOption('ca', process.env.DATABASE_SSL_CA_FILE, options);

return options;
};

const defaultDbOptions: WithOptional<IDBOption, 'user' | 'password' | 'host'> =
Expand All @@ -229,7 +237,7 @@ const defaultDbOptions: WithOptional<IDBOption, 'user' | 'password' | 'host'> =
host: process.env.DATABASE_HOST,
port: parseEnvVarNumber(process.env.DATABASE_PORT, 5432),
database: process.env.DATABASE_NAME || 'unleash',
ssl: databaseSsl(),
ssl: databaseSSL(),
driver: 'postgres',
version: process.env.DATABASE_VERSION,
acquireConnectionTimeout: secondsToMilliseconds(30),
Expand Down Expand Up @@ -491,16 +499,14 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
extraDbOptions = parse(process.env.DATABASE_URL);
}
let fileDbOptions = {};
if (options.databaseUrlFile && fs.existsSync(options.databaseUrlFile)) {
fileDbOptions = parse(
fs.readFileSync(options.databaseUrlFile, 'utf-8'),
);
if (options.databaseUrlFile && existsSync(options.databaseUrlFile)) {
fileDbOptions = parse(readFileSync(options.databaseUrlFile, 'utf-8'));
} else if (
process.env.DATABASE_URL_FILE &&
fs.existsSync(process.env.DATABASE_URL_FILE)
existsSync(process.env.DATABASE_URL_FILE)
) {
fileDbOptions = parse(
fs.readFileSync(process.env.DATABASE_URL_FILE, 'utf-8'),
readFileSync(process.env.DATABASE_URL_FILE, 'utf-8'),
);
}
const db: IDBOption = mergeAll<IDBOption>([
Expand Down

0 comments on commit 60f637f

Please sign in to comment.