Skip to content

Commit

Permalink
feat: added tls config
Browse files Browse the repository at this point in the history
Signed-off-by: Avinash <avinash.kumar.cs92@gmail.com>
  • Loading branch information
Avinash committed Mar 14, 2024
1 parent 956dd28 commit 0a903aa
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 8 deletions.
3 changes: 3 additions & 0 deletions backend/src/config/database.config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import mockedEnv from 'mocked-env';

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused import mockedEnv.

describe('databaseConfig', () => {});
66 changes: 66 additions & 0 deletions backend/src/config/database.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { registerAs } from '@nestjs/config';
import * as fs from 'fs';
import * as Joi from 'joi';

import { DatabaseType } from './database-type.enum';
Expand All @@ -18,10 +19,31 @@ export interface DatabaseConfig {
type: DatabaseType;
}

const getSecret = (path?: string) => {
if (path && fs.existsSync(path)) {
return fs.readFileSync(path, 'utf8');
}
};

const sqlTlsSchema = Joi.object({
rejectUnauthorized: Joi.boolean()
.default(true)
.label('HD_DATABASE_SSL_REJECT_UNAUTHORIZED')
.optional(),
ca: Joi.string().label('HD_DATABASE_SSL_CA_PATH'),
cert: Joi.string().label('HD_DATABASE_SSL_CERT_PATH').optional(),
key: Joi.string().label('HD_DATABASE_SSL_KEY_PATH').optional(),
ciphers: Joi.string().label('HD_DATABASE_SSL_CIPHERS').optional(),
maxVersion: Joi.string().label('HD_DATABASE_SSL_MAX_VERSION').optional(),
minVersion: Joi.string().label('HD_DATABASE_SSL_MIN_VERSION').optional(),
passphrase: Joi.string().label('HD_DATABASE_SSL_PASSPHRASE').optional(),
});

const databaseSchema = Joi.object({
type: Joi.string()
.valid(...Object.values(DatabaseType))
.label('HD_DATABASE_TYPE'),
needsSSL: Joi.boolean().label('HD_DATABASE_SSL'),

// This is the database name, except for SQLite,
// where it is the path to the database file.
Expand All @@ -46,17 +68,61 @@ const databaseSchema = Joi.object({
then: Joi.number(),
otherwise: Joi.optional(),
}).label('HD_DATABASE_PORT'),
ssl: Joi.when('needsSSL', {
is: Joi.valid('1'),
then: Joi.required(),
otherwise: Joi.optional(),
}).when('type', {
is: Joi.valid(
DatabaseType.MARIADB,
DatabaseType.MYSQL,
DatabaseType.SQLITE,
),
then: sqlTlsSchema,
otherwise: Joi.optional(),
}),
});

const getTlsConfig = (dbType: DatabaseType, needsSSL: boolean) => {
if (!needsSSL) {
return;
}

const sqlTlsConfig = [DatabaseType.MARIADB, DatabaseType.MYSQL].includes(
dbType,
) && {
ssl: {
ca: getSecret(process.env.HD_DATABASE_SSL_CA_PATH),
key: getSecret(process.env.HD_DATABASE_SSL_KEY_PATH),
cert: getSecret(process.env.HD_DATABASE_SSL_CERT_PATH),
rejectUnauthorized:
process.env.HD_DATABASE_SSL_REJECT_UNAUTHORIZED === 'true',
ciphers: process.env.HD_DATABASE_SSL_CIPHERS,
maxVersion: process.env.HD_DATABASE_SSL_MAX_VERSION,
minVersion: process.env.HD_DATABASE_SSL_MIN_VERSION,
passphrase: process.env.HD_DATABASE_SSL_PASSPHRASE,
},
};

return sqlTlsConfig;
};

const dbType = process.env.HD_DATABASE_TYPE;
const needsSSL = process.env.HD_DATABASE_SSL === '1';

const tlsConfig = getTlsConfig(dbType as DatabaseType, needsSSL);

export default registerAs('databaseConfig', () => {
const databaseConfig = databaseSchema.validate(
{
needsSSL,
type: process.env.HD_DATABASE_TYPE,
username: process.env.HD_DATABASE_USER,
password: process.env.HD_DATABASE_PASS,
database: process.env.HD_DATABASE_NAME,
host: process.env.HD_DATABASE_HOST,
port: parseOptionalNumber(process.env.HD_DATABASE_PORT),
...tlsConfig,
},
{
abortEarly: false,
Expand Down
40 changes: 32 additions & 8 deletions docs/content/references/config/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,36 @@ We officially support and test these databases:
- MariaDB

<!-- markdownlint-disable proper-names -->
| environment variable | default | example | description |
|-----------------------|---------|---------------------|--------------------------------------------------------------------------------------------|
| `HD_DATABASE_TYPE` | - | `postgres` | The database type you want to use. This can be `postgres`, `mysql`, `mariadb` or `sqlite`. |
| `HD_DATABASE_NAME` | - | `hedgedoc` | The name of the database to use. When using SQLite, this is the path to the database file. |
| `HD_DATABASE_HOST` | - | `db.example.com` | The host, where the database runs. *Only if you're **not** using `sqlite`.* |
| `HD_DATABASE_PORT` | - | `5432` | The port, where the database runs. *Only if you're **not** using `sqlite`.* |
| `HD_DATABASE_USER` | - | `hedgedoc` | The user that logs in the database. *Only if you're **not** using `sqlite`.* |
| `HD_DATABASE_PASS` | - | `password` | The password to log into the database. *Only if you're **not** using `sqlite`.* |

| environment variable | default | example | description |
| -------------------- | ------- | ---------------- | ------------------------------------------------------------------------------------------ |
| `HD_DATABASE_TYPE` | - | `postgres` | The database type you want to use. This can be `postgres`, `mysql`, `mariadb` or `sqlite`. |
| `HD_DATABASE_NAME` | - | `hedgedoc` | The name of the database to use. When using SQLite, this is the path to the database file. |
| `HD_DATABASE_HOST` | - | `db.example.com` | The host, where the database runs. _Only if you're **not** using `sqlite`._ |
| `HD_DATABASE_PORT` | - | `5432` | The port, where the database runs. _Only if you're **not** using `sqlite`._ |
| `HD_DATABASE_USER` | - | `hedgedoc` | The user that logs in the database. _Only if you're **not** using `sqlite`._ |
| `HD_DATABASE_PASS` | - | `password` | The password to log into the database. _Only if you're **not** using `sqlite`._ |
| `HD_DATABASE_SSL` | '0' | `1` | Pass this value when SSL/TLS configuration is needed |

### SSL/TLS configuration for database

**Note:** `HD_DATABASE_SSL='1'` should be added in .env else following SSL/TLS config will not work

<!-- markdownlint-disable proper-names -->

| environment variable | default | example | description |
| ------------------------------------- | ------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HD_DATABASE_SSL_CA_PATH` | - | ./mysql-ca.crt | The path of SSL/TLS certificate authority (CA) certificate needed for establishing secure database connections |
| `HD_DATABASE_SSL_CERT_PATH` | - | ./mysql-cert.crt | The path for client certificate to use in the SSL handshake. |
| `HD_DATABASE_SSL_REJECT_UNAUTHORIZED` | 'true' | 'false' | If true server certificate will be verified against the list of supplied CAs. |
| `HD_DATABASE_SSL_KEY_PATH` | - | ./key.pem | This is passed as the key option to [SSL key option](https://github.com/mysqljs/mysql?tab=readme-ov-file#ssl-options) |
| `HD_DATABASE_SSL_CIPHERS` | - | 'TLS_AES_256...' | The ciphers to use to use in the SSL handshake instead of the default ones for Node.js. |
| `HD_DATABASE_SSL_MAX_VERSION` | - | 'TLSv1.3' | This is passed as the maxVersion option for [SSL max_version](https://github.com/mysqljs/mysql?tab=readme-ov-file#ssl-options) |
| `HD_DATABASE_SSL_MIN_VERSION` | - | 'TLSv1.3' | This is passed as the minVersion option for [SSL max_version](https://github.com/mysqljs/mysql?tab=readme-ov-file#ssl-options) |
| `HD_DATABASE_SSL_PASSPHRASE` | - | 'XSX@W...' | Shared passphrase used for a single private key and/or a PFX.This is passed as the passphrase option for [SSL max_version](https://github.com/mysqljs/mysql?tab=readme-ov-file#ssl-options) |

This CA certificate serves as the anchor for verifying the validity of the certificate chain. Ensure that the provided CA certificate is trusted by the database server to establish secure connections.

Check full description for [mysql TLS](https://github.com/mysqljs/mysql?tab=readme-ov-file#ssl-options)

<!-- markdownlint-enable proper-names -->

0 comments on commit 0a903aa

Please sign in to comment.