diff --git a/package.json b/package.json index 9bda3ca6e..0fd29feaf 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ }, "dependencies": { "@nestjs/common": "7.6.5", + "@nestjs/config": "^0.6.1", "@nestjs/core": "7.6.5", "@nestjs/platform-express": "7.6.5", "@nestjs/swagger": "4.7.10", @@ -34,6 +35,7 @@ "cli-color": "2.0.0", "connect-typeorm": "1.1.4", "file-type": "16.2.0", + "joi": "^17.3.0", "raw-body": "2.4.1", "reflect-metadata": "0.1.13", "rimraf": "3.0.2", diff --git a/src/app.module.ts b/src/app.module.ts index 3cef03730..a693d86a1 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -5,6 +5,7 @@ */ import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { PublicApiModule } from './api/public/public-api.module'; import { AuthorsModule } from './authors/authors.module'; @@ -17,6 +18,7 @@ import { NotesModule } from './notes/notes.module'; import { PermissionsModule } from './permissions/permissions.module'; import { RevisionsModule } from './revisions/revisions.module'; import { UsersModule } from './users/users.module'; +import appConfig from './config/app.config'; @Module({ imports: [ @@ -26,6 +28,9 @@ import { UsersModule } from './users/users.module'; autoLoadEntities: true, synchronize: true, }), + ConfigModule.forRoot({ + load: [appConfig], + }), NotesModule, UsersModule, RevisionsModule, diff --git a/src/config/app.config.ts b/src/config/app.config.ts new file mode 100644 index 000000000..122fda6f9 --- /dev/null +++ b/src/config/app.config.ts @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { registerAs } from '@nestjs/config'; +import * as Joi from 'joi'; + +export interface AppConfig { + port: number; + media: { + backend: { + use: string; + filesystem: { + uploadPath: string; + }; + }; + }; +} + +const schema = Joi.object({ + port: Joi.number(), + media: { + backend: { + use: Joi.string().valid('filesystem'), + filesystem: { + uploadPath: Joi.when('...use', { + is: Joi.valid('filesystem'), + then: Joi.string(), + otherwise: Joi.optional(), + }), + }, + }, + }, +}); + +export default registerAs('appConfig', async () => { + const appConfig = schema.validate( + { + port: parseInt(process.env.PORT) || undefined, + media: { + backend: { + use: process.env.HD_MEDIA_BACKEND, + filesystem: { + uploadPath: process.env.HD_MEDIA_BACKEND_FILESYSTEM_UPLOAD_PATH, + }, + }, + }, + }, + { + abortEarly: false, + presence: 'required', + }, + ); + if (appConfig.error) { + throw new Error(appConfig.error.toString()); + } + return appConfig.value; +}); diff --git a/yarn.lock b/yarn.lock index a2365d24e..a44462f45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -367,6 +367,18 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@hapi/hoek@^9.0.0": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa" + integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw== + +"@hapi/topo@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" + integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw== + dependencies: + "@hapi/hoek" "^9.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -592,6 +604,18 @@ tslib "2.0.3" uuid "8.3.2" +"@nestjs/config@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@nestjs/config/-/config-0.6.1.tgz#26e4bfd4b2f9d3a6b6bed6445a2a1e766abdf1c6" + integrity sha512-sSIEbHp0xV7bneG2/CePqJh60ELojsBXBPuRM40AcVQwuDRQQ4RAnLT5uaJbWB2xFQjQwik4zejN+27t1cCiBQ== + dependencies: + dotenv "8.2.0" + dotenv-expand "5.1.0" + lodash.get "4.4.2" + lodash.has "4.5.2" + lodash.set "4.3.2" + uuid "8.3.1" + "@nestjs/core@7.6.5": version "7.6.5" resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-7.6.5.tgz#93c642d1abf8d3f09f8f78c262814eaf83bc2ad6" @@ -703,6 +727,23 @@ "@angular-devkit/core" "11.0.3" "@angular-devkit/schematics" "11.0.3" +"@sideway/address@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.0.tgz#0b301ada10ac4e0e3fa525c90615e0b61a72b78d" + integrity sha512-wAH/JYRXeIFQRsxerIuLjgUu2Xszam+O5xKeatJ4oudShOOirfmsQ1D6LL54XOU2tizpCYku+s1wmU0SYdpoSA== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" + integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + "@sinonjs/commons@^1.7.0": version "1.7.2" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.2.tgz#505f55c74e0272b43f6c52d81946bed7058fc0e2" @@ -2454,7 +2495,12 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -dotenv@^8.2.0: +dotenv-expand@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@8.2.0, dotenv@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== @@ -4344,6 +4390,17 @@ jest@26.6.3: import-local "^3.0.2" jest-cli "^26.6.3" +joi@^17.3.0: + version "17.3.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.3.0.tgz#f1be4a6ce29bc1716665819ac361dfa139fff5d2" + integrity sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.0" + "@sideway/formula" "^3.0.0" + "@sideway/pinpoint" "^2.0.0" + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -4566,11 +4623,26 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash.get@4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.has@4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862" + integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI= + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.set@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" + integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"