Add support for _FILE environment variables (#6101)

* Add support for _FILE environment variables

* Enhance processing of _FILE env vars

* Same processing as with other env vars (do not simply treat as string)
- tested successfully
* Warn if both variables are set (EXAMPLE and EXAMPLE_FILE)
* Add comments to make it easier to understand the code

* Set newKey only after file read was successful

* Don't convert value > MAX_SAFE_INTEGER to number

Thanks to @skizer!

As stated by @skizer (from #6119):
  Altho it seems that we do have a numerical value
  it can happen that its outside of Number.MAX_SAFE_INTEGER
  thus resulting in a change of the original intended value
  e.g oauth -> discord -> client_id

* Fix recursive logger-env import

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
Pascal Jufer
2021-06-09 20:08:26 +02:00
committed by GitHub
parent 1a867f17d1
commit a2a35aaab5
4 changed files with 80 additions and 31 deletions

View File

@@ -7,11 +7,10 @@ import dotenv from 'dotenv';
import fs from 'fs';
import { clone, toNumber, toString } from 'lodash';
import path from 'path';
import logger from './logger';
import { requireYAML } from './utils/require-yaml';
import { toArray } from './utils/to-array';
const acceptableEnvTypes = ['string', 'number', 'regex', 'array'];
const acceptedEnvTypes = ['string', 'number', 'regex', 'array'];
const defaults: Record<string, any> = {
CONFIG_PATH: path.resolve(process.cwd(), '.env'),
@@ -125,7 +124,7 @@ function getEnv() {
return exported;
}
logger.warn(
throw new Error(
`Invalid JS configuration file export type. Requires one of "function", "object", received: "${typeof exported}"`
);
}
@@ -141,11 +140,11 @@ function getEnv() {
return data as Record<string, string>;
}
logger.warn('Invalid YAML configuration. Root has to ben an object.');
throw new Error('Invalid YAML configuration. Root has to be an object.');
}
// Default to env vars plain text files
return dotenv.parse(fs.readFileSync(configPath).toString());
return dotenv.parse(fs.readFileSync(configPath, { encoding: 'utf8' }));
}
function getVariableType(variable: string) {
@@ -175,12 +174,33 @@ function getEnvironmentValueByType(envVariableString: string) {
function processValues(env: Record<string, any>) {
env = clone(env);
for (const [key, value] of Object.entries(env)) {
if (typeof value === 'string' && acceptableEnvTypes.some((envType) => value.includes(`${envType}:`))) {
for (let [key, value] of Object.entries(env)) {
// If key ends with '_FILE', try to get the value from the file defined in this variable
// and store it in the variable with the same name but without '_FILE' at the end
let newKey;
if (key.length > 5 && key.endsWith('_FILE')) {
try {
value = fs.readFileSync(value, { encoding: 'utf8' });
newKey = key.slice(0, -5);
if (newKey in env) {
throw new Error(
`Duplicate environment variable encountered: you can't use "${key}" and "${newKey}" simultaneously.`
);
}
key = newKey;
} catch {
throw new Error(`Failed to read value from file "${value}", defined in environment variable "${key}".`);
}
}
// Convert values with a type prefix
// (see https://docs.directus.io/reference/environment-variables/#environment-syntax-prefix)
if (typeof value === 'string' && acceptedEnvTypes.some((envType) => value.includes(`${envType}:`))) {
env[key] = getEnvironmentValueByType(value);
continue;
}
// Convert values where the key is defined in typeMap
if (typeMap[key]) {
switch (typeMap[key]) {
case 'number':
@@ -193,20 +213,34 @@ function processValues(env: Record<string, any>) {
env[key] = toArray(value);
break;
}
continue;
}
if (value === 'true') env[key] = true;
else if (value === 'false') env[key] = false;
else if (value === 'null') env[key] = null;
else if (
// Try to convert remaining values:
// - boolean values to boolean
// - 'null' to null
// - number values (> 0 <= Number.MAX_SAFE_INTEGER) to number
if (value === 'true' || value === 'false') {
env[key] = !!value;
continue;
}
if (value === 'null') {
env[key] = null;
continue;
}
if (
String(value).startsWith('0') === false &&
isNaN(value) === false &&
value.length > 0 &&
value < Number.MAX_SAFE_INTEGER // Make sure we don't treat long numeric ID strings as numbers
value <= Number.MAX_SAFE_INTEGER
) {
env[key] = Number(value);
continue;
}
// If '_FILE' variable hasn't been processed yet, store it as it is (string)
if (newKey) {
env[key] = value;
}
}

View File

@@ -7,32 +7,46 @@ _Changes marked with a :warning: contain potential breaking changes depending on
### :sparkles: New Features
- **API**
- [#6116](https://github.com/directus/directus/pull/6116) Add support for CRON hooks (interval) ([@rijkvanzanten](https://github.com/rijkvanzanten))
- [#6116](https://github.com/directus/directus/pull/6116) Add support for CRON hooks (interval)
([@rijkvanzanten](https://github.com/rijkvanzanten))
### :rocket: Improvements
- **App**
- [#6112](https://github.com/directus/directus/pull/6112) Make mfa output code selectable ([@rijkvanzanten](https://github.com/rijkvanzanten))
- [#6112](https://github.com/directus/directus/pull/6112) Make mfa output code selectable
([@rijkvanzanten](https://github.com/rijkvanzanten))
- **Docker**
- [#6081](https://github.com/directus/directus/pull/6081) Optimize Docker image performance and formatting ([@paescuj](https://github.com/paescuj))
- [#6081](https://github.com/directus/directus/pull/6081) Optimize Docker image performance and formatting
([@paescuj](https://github.com/paescuj))
### :memo: Documentation
- [#6110](https://github.com/directus/directus/pull/6110) Improve search ability of update instructions ([@benhaynes](https://github.com/benhaynes))
- [#6110](https://github.com/directus/directus/pull/6110) Improve search ability of update instructions
([@benhaynes](https://github.com/benhaynes))
- [#6087](https://github.com/directus/directus/pull/6087) Fix typo ([@benhaynes](https://github.com/benhaynes))
- [#6086](https://github.com/directus/directus/pull/6086) Update introduction.md ([@benhaynes](https://github.com/benhaynes))
- [#6086](https://github.com/directus/directus/pull/6086) Update introduction.md
([@benhaynes](https://github.com/benhaynes))
### :package: Dependency Updates
- [#6109](https://github.com/directus/directus/pull/6109) Bump vue-loader from 15.9.6 to 15.9.7 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6108](https://github.com/directus/directus/pull/6108) Bump @types/yargs from 16.0.1 to 17.0.0 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6107](https://github.com/directus/directus/pull/6107) Bump mime-types from 2.1.30 to 2.1.31 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6106](https://github.com/directus/directus/pull/6106) Bump graphql-compose from 8.1.0 to 9.0.1 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6105](https://github.com/directus/directus/pull/6105) Bump jest from 27.0.3 to 27.0.4 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6082](https://github.com/directus/directus/pull/6082) Bump @godaddy/terminus from 4.7.2 to 4.9.0 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6069](https://github.com/directus/directus/pull/6069) Bump @fullcalendar/list from 5.7.0 to 5.7.2 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6068](https://github.com/directus/directus/pull/6068) Bump aws-sdk from 2.911.0 to 2.921.0 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6066](https://github.com/directus/directus/pull/6066) Bump @types/node from 15.9.0 to 15.12.0 ([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6109](https://github.com/directus/directus/pull/6109) Bump vue-loader from 15.9.6 to 15.9.7
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6108](https://github.com/directus/directus/pull/6108) Bump @types/yargs from 16.0.1 to 17.0.0
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6107](https://github.com/directus/directus/pull/6107) Bump mime-types from 2.1.30 to 2.1.31
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6106](https://github.com/directus/directus/pull/6106) Bump graphql-compose from 8.1.0 to 9.0.1
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6105](https://github.com/directus/directus/pull/6105) Bump jest from 27.0.3 to 27.0.4
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6082](https://github.com/directus/directus/pull/6082) Bump @godaddy/terminus from 4.7.2 to 4.9.0
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6069](https://github.com/directus/directus/pull/6069) Bump @fullcalendar/list from 5.7.0 to 5.7.2
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6068](https://github.com/directus/directus/pull/6068) Bump aws-sdk from 2.911.0 to 2.921.0
([@dependabot[bot]](https://github.com/apps/dependabot))
- [#6066](https://github.com/directus/directus/pull/6066) Bump @types/node from 15.9.0 to 15.12.0
([@dependabot[bot]](https://github.com/apps/dependabot))
## v9.0.0-rc.73 (June 4, 2021)

View File

@@ -18,8 +18,8 @@ developers and an intuitive App for non-technical users.** Written entirely in J
[Node.js](https://nodejs.dev) and [Vue.js](https://vuejs.org)), Directus is completely open-source, modular, and
extensible, allowing it to be fully tailored to the requirements of any project.
The platform can be used for an individual purpose, such as headless content management, or more broadly to democratize an entire organization's data (customers, inventory, business intelligence,
projects, etc).
The platform can be used for an individual purpose, such as headless content management, or more broadly to democratize
an entire organization's data (customers, inventory, business intelligence, projects, etc).
::: tip What's in a name?

View File

@@ -67,7 +67,8 @@ interfaces, displays, and their options for your fields.
This would also be a good time to reconfigure your permissions, to ensure they are accurate.
## Breaking changes
- [Filter operators](/reference/filter-rules.md) have changed, now they are preceeded with an underscore eg: `/items/users?filter[comments.thread.title][like]=Directus` is now `/items/users?filter[comments][thread][title][_like]=Directus`
- [Filter operators](/reference/filter-rules.md) have changed, now they are preceeded with an underscore eg:
`/items/users?filter[comments.thread.title][like]=Directus` is now
`/items/users?filter[comments][thread][title][_like]=Directus`