From 5ee253c953807bdb795ecef236e8d0f2f60de890 Mon Sep 17 00:00:00 2001 From: Matthias Kunnen Date: Fri, 9 Jun 2023 19:37:20 +0200 Subject: [PATCH 1/2] test(): unexpected stringification of variables assigned to process.env After validation, environment variables are assigned back to process.env. This leads to stringification of the values. This stringification is deprecated and might result in a runtime error in the future. See https://nodejs.org/api/process.html#processenv. A special case is when an environment variable has the value `undefined`. This causes `ConfigService.get` to fall back on process.env thereby returning the stringified form `'undefined'`. --- tests/e2e/optional.spec.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/e2e/optional.spec.ts diff --git a/tests/e2e/optional.spec.ts b/tests/e2e/optional.spec.ts new file mode 100644 index 00000000..f568158d --- /dev/null +++ b/tests/e2e/optional.spec.ts @@ -0,0 +1,33 @@ +import { Test } from '@nestjs/testing'; +import { AppModule } from '../src/app.module'; +import { ConfigService } from '../../lib'; + +describe('Optional environment variables', () => { + it('should return undefined for optional variables', async () => { + const module = await Test.createTestingModule({ + imports: [AppModule.withValidateFunction(() => ({ + optional: undefined, + }))], + }).compile(); + + const app = module.createNestApplication(); + await app.init(); + + const optional = module.get(ConfigService).get('optional') + + expect(optional).toEqual(undefined) + }); + + it('should not assign complex objects back to process.env', async () => { + const module = await Test.createTestingModule({ + imports: [AppModule.withValidateFunction(() => ({ + complex: {hello: 'there'}, + }))], + }).compile(); + + const app = module.createNestApplication(); + await app.init(); + + expect(process.env.complex).toEqual(undefined) + }); +}); From efdb29ea998fdf0875277ba4de981c2528238634 Mon Sep 17 00:00:00 2001 From: Matthias Kunnen Date: Sun, 30 Apr 2023 22:24:08 +0200 Subject: [PATCH 2/2] fix(): do not assign a non-string to process.env Assigning a value to process.env[] leads to stringification of the value. Example: ``` > process.env.test = {} > process.env.test '[object Object]' ``` This problem was hidden because `ConfigService.get` returns the value of the validated config which would not be stringified. A special case is when an environment variable has the value `undefined`. This is because `ConfigService.get` falls back to process.env which returns the stringified form `'undefined'`. The stringification is deprecated and might result in a runtime error in the future. See https://nodejs.org/api/process.html#processenv. The argument has been changed to Record to be more type-safe. If this type was used in the original code, this bug could have been avoided. --- lib/config.module.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/config.module.ts b/lib/config.module.ts index b912d101..45437970 100644 --- a/lib/config.module.ts +++ b/lib/config.module.ts @@ -192,13 +192,18 @@ export class ConfigModule { return config; } - private static assignVariablesToProcess(config: Record) { + private static assignVariablesToProcess(config: Record) { if (!isObject(config)) { return; } const keys = Object.keys(config).filter(key => !(key in process.env)); keys.forEach( - key => (process.env[key] = (config as Record)[key]), + key => { + const value = config[key]; + if (typeof value === 'string') { + process.env[key] = value; + } + }, ); }