mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-04-06 15:30:30 +08:00
feat(server): read secrets from env variables
This commit is contained in:
parent
5f2a43bb81
commit
6478d266a4
29
.pnp.js
generated
29
.pnp.js
generated
@ -3983,18 +3983,21 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"packageLocation": "./packages/server/",
|
||||
"packageDependencies": [
|
||||
["@lowdefy/server", "workspace:packages/server"],
|
||||
["@babel/cli", "virtual:4a7337632ff6e9ee5a1c45a62a9ff4cc325a9367b21424babda93e269fe01b671e885bc41bdeebafb83c81f2a8eebbf0102043354a4e58905f61c8c3387cda1e#npm:7.12.1"],
|
||||
["@babel/core", "npm:7.12.3"],
|
||||
["@babel/preset-env", "virtual:4a7337632ff6e9ee5a1c45a62a9ff4cc325a9367b21424babda93e269fe01b671e885bc41bdeebafb83c81f2a8eebbf0102043354a4e58905f61c8c3387cda1e#npm:7.12.1"],
|
||||
["@babel/preset-react", "virtual:22157ea722f8d6428f1fcf0a6f7f6c7d6b902d9c785256c60a65fe6cd0db76ebccc7c1457ee047df0ba6909ff018e300c4f4957a60f5b670089810dfc417af9b#npm:7.12.5"],
|
||||
["@lowdefy/block-tools", "workspace:packages/blockTools"],
|
||||
["@lowdefy/graphql", "workspace:packages/graphql"],
|
||||
["apollo-server-express", "virtual:1e43113c7dc84a5d03308bf7ffaf00574d351ca16282af6c6c0b9576804fb03914bdf2200961292f439926b2e537dce172d7529f79013ce51b9f2d56e9cd836b#npm:2.19.0"],
|
||||
["babel-jest", "virtual:caddf51df4928b33a437ca87b8f5ddfb6205ebd6d8231f74d4ee7223f3866e6f815b221aa1e2bd33e98915f701e95bae72a93d2288b49a34a6246bdbc2a4a132#npm:26.6.3"],
|
||||
["babel-loader", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:8.2.1"],
|
||||
["clean-webpack-plugin", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:3.0.0"],
|
||||
["copy-webpack-plugin", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:6.3.0"],
|
||||
["css-loader", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:5.0.1"],
|
||||
["express", "npm:4.17.1"],
|
||||
["graphql", "npm:15.4.0"],
|
||||
["html-webpack-plugin", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:4.5.0"],
|
||||
["jest", "npm:26.6.3"],
|
||||
["nodemon", "npm:2.0.6"],
|
||||
["react", "npm:17.0.1"],
|
||||
["react-dom", "virtual:22157ea722f8d6428f1fcf0a6f7f6c7d6b902d9c785256c60a65fe6cd0db76ebccc7c1457ee047df0ba6909ff018e300c4f4957a60f5b670089810dfc417af9b#npm:17.0.1"],
|
||||
@ -9129,30 +9132,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]
|
||||
]],
|
||||
["copy-webpack-plugin", [
|
||||
["virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:6.3.0", {
|
||||
"packageLocation": "./.yarn/$$virtual/copy-webpack-plugin-virtual-9c7083a2fa/0/cache/copy-webpack-plugin-npm-6.3.0-0a315a2450-edca6ec5cd.zip/node_modules/copy-webpack-plugin/",
|
||||
"packageDependencies": [
|
||||
["copy-webpack-plugin", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:6.3.0"],
|
||||
["@types/webpack", null],
|
||||
["cacache", "npm:15.0.5"],
|
||||
["fast-glob", "npm:3.2.4"],
|
||||
["find-cache-dir", "npm:3.3.1"],
|
||||
["glob-parent", "npm:5.1.1"],
|
||||
["globby", "npm:11.0.1"],
|
||||
["loader-utils", "npm:2.0.0"],
|
||||
["normalize-path", "npm:3.0.0"],
|
||||
["p-limit", "npm:3.0.2"],
|
||||
["schema-utils", "npm:3.0.0"],
|
||||
["serialize-javascript", "npm:5.0.1"],
|
||||
["webpack", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:5.4.0"],
|
||||
["webpack-sources", "npm:1.4.3"]
|
||||
],
|
||||
"packagePeers": [
|
||||
"@types/webpack",
|
||||
"webpack"
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}],
|
||||
["virtual:65bbdbc833194d48af8b473ccb9eb396af4cb12a8148bcea865208cb4df1306b9afb0a62408cbd348e6f2af9b92764096868c744881c07da8a59708a1c9cb4f4#npm:6.3.0", {
|
||||
"packageLocation": "./.yarn/$$virtual/copy-webpack-plugin-virtual-30f062ffd9/0/cache/copy-webpack-plugin-npm-6.3.0-0a315a2450-edca6ec5cd.zip/node_modules/copy-webpack-plugin/",
|
||||
"packageDependencies": [
|
||||
|
14
packages/server/.babelrc
Normal file
14
packages/server/.babelrc
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"node": "12",
|
||||
"esmodules": true
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"ignore": ["./src/shell"]
|
||||
}
|
11
packages/server/jest.config.js
Normal file
11
packages/server/jest.config.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
collectCoverage: true,
|
||||
collectCoverageFrom: ['src/**/*.js'],
|
||||
coverageDirectory: 'coverage',
|
||||
coveragePathIgnorePatterns: ['<rootDir>/dist/', '<rootDir>/test/', '<rootDir>/src/shell/'],
|
||||
coverageReporters: [['lcov', { projectRoot: '../..' }], 'text', 'clover'],
|
||||
errorOnDeprecated: true,
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: ['<rootDir>/dist/', '<rootDir>/.lowdefy/'],
|
||||
};
|
@ -25,17 +25,22 @@
|
||||
"dist/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "webpack --config webpack.prod.js",
|
||||
"build:dev": "webpack --config webpack.dev.js",
|
||||
"babel": "babel src --out-dir dist",
|
||||
"babel:dev": "babel src --out-dir dev",
|
||||
"build": "yarn webpack && yarn babel",
|
||||
"build:dev": "yarn webpack:dev && yarn babel:dev",
|
||||
"build:docker": "docker build --tag lowdefy/lowdefy .",
|
||||
"clean": "rm -rf dist",
|
||||
"clean": "rm -rf dist && rm -rf dev",
|
||||
"npm-publish": "npm publish --access public",
|
||||
"prepublishOnly": "yarn build",
|
||||
"start": "nodemon dev/server.js",
|
||||
"test": "jest --coverage",
|
||||
"version:prerelease": "yarn version prerelease",
|
||||
"version:patch": "yarn version patch -d",
|
||||
"version:minor": "yarn version minor -d",
|
||||
"version:major": "yarn version major -d"
|
||||
"version:major": "yarn version major -d",
|
||||
"webpack": "webpack --config webpack.prod.js",
|
||||
"webpack:dev": "webpack --config webpack.dev.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lowdefy/block-tools": "1.0.2",
|
||||
@ -47,13 +52,16 @@
|
||||
"react-dom": "17.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.12.1",
|
||||
"@babel/core": "7.12.3",
|
||||
"@babel/preset-env": "7.12.1",
|
||||
"@babel/preset-react": "7.12.5",
|
||||
"babel-jest": "26.6.3",
|
||||
"babel-loader": "8.2.1",
|
||||
"clean-webpack-plugin": "3.0.0",
|
||||
"copy-webpack-plugin": "6.3.0",
|
||||
"css-loader": "5.0.1",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"jest": "26.6.3",
|
||||
"nodemon": "2.0.6",
|
||||
"style-loader": "2.0.0",
|
||||
"webpack": "5.4.0",
|
||||
|
29
packages/server/src/createGetSecretsFromEnv.js
Normal file
29
packages/server/src/createGetSecretsFromEnv.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2020 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
function createGetSecretsFromEnv() {
|
||||
const secrets = {};
|
||||
|
||||
Object.keys(process.env).forEach((key) => {
|
||||
if (key.startsWith('LOWDEFY_SECRET_')) {
|
||||
secrets[key.replace('LOWDEFY_SECRET_', '')] = process.env[key];
|
||||
}
|
||||
});
|
||||
Object.freeze(secrets);
|
||||
return () => secrets;
|
||||
}
|
||||
|
||||
export default createGetSecretsFromEnv;
|
@ -14,21 +14,17 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const express = require('express');
|
||||
const { ApolloServer } = require('apollo-server-express');
|
||||
const { typeDefs, resolvers, createContext } = require('@lowdefy/graphql');
|
||||
import path from 'path';
|
||||
import express from 'express';
|
||||
import { ApolloServer } from 'apollo-server-express';
|
||||
import { typeDefs, resolvers, createContext } from '@lowdefy/graphql';
|
||||
|
||||
import createGetSecretsFromEnv from './createGetSecretsFromEnv';
|
||||
|
||||
const config = {
|
||||
DEPLOYMENT_ID: 'DEPLOYMENT_ID',
|
||||
DEPLOYMENT_NAME: 'DEPLOYMENT_NAME',
|
||||
DOMAIN_NAME: 'DOMAIN_NAME',
|
||||
CONFIGURATION_BASE_PATH: path.resolve(process.cwd(), './.lowdefy/build'),
|
||||
logger: console,
|
||||
getHeadersFromInput: ({ req }) => req.headers,
|
||||
getSecrets: () => ({
|
||||
CONNECTION_SECRETS: {},
|
||||
}),
|
||||
getSecrets: createGetSecretsFromEnv(),
|
||||
};
|
||||
|
||||
const context = createContext(config);
|
||||
|
90
packages/server/test/createGetSecretsFromEnv.test.js
Normal file
90
packages/server/test/createGetSecretsFromEnv.test.js
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2020 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import createGetSecretsFromEnv from '../src/createGetSecretsFromEnv';
|
||||
|
||||
const realEnv = process.env;
|
||||
|
||||
afterEach(() => {
|
||||
process.env = realEnv;
|
||||
});
|
||||
|
||||
test('Get secret from env', () => {
|
||||
process.env = {
|
||||
LOWDEFY_SECRET_TEST: 'supersecret',
|
||||
};
|
||||
const getSecrets = createGetSecretsFromEnv();
|
||||
expect(getSecrets()).toEqual({
|
||||
TEST: 'supersecret',
|
||||
});
|
||||
});
|
||||
|
||||
test('Get multiple secrets from env, ignore other env variable', () => {
|
||||
process.env = {
|
||||
LOWDEFY_SECRET_TEST_1: 'supersecret1',
|
||||
LOWDEFY_SECRET_TEST_2: 'supersecret2',
|
||||
OTHER_VAR: 'other',
|
||||
ANOTHER_VAR: 'another',
|
||||
ASDF_GHJK: 'asdfghjk',
|
||||
};
|
||||
const getSecrets = createGetSecretsFromEnv();
|
||||
expect(getSecrets()).toEqual({
|
||||
TEST_1: 'supersecret1',
|
||||
TEST_2: 'supersecret2',
|
||||
});
|
||||
});
|
||||
|
||||
test('Only replace first occurrence of "LOWDEFY_SECRET_"', () => {
|
||||
process.env = {
|
||||
LOWDEFY_SECRET_LOWDEFY_SECRET_TEST: 'supersecret',
|
||||
};
|
||||
const getSecrets = createGetSecretsFromEnv();
|
||||
expect(getSecrets()).toEqual({
|
||||
LOWDEFY_SECRET_TEST: 'supersecret',
|
||||
});
|
||||
});
|
||||
|
||||
test('Return an empty object if no secrets', () => {
|
||||
process.env = {
|
||||
OTHER_VAR: 'other',
|
||||
ANOTHER_VAR: 'another',
|
||||
ASDF_GHJK: 'asdfghjk',
|
||||
};
|
||||
const getSecrets = createGetSecretsFromEnv();
|
||||
expect(getSecrets()).toEqual({});
|
||||
});
|
||||
|
||||
test('Return the same object', () => {
|
||||
process.env = {
|
||||
LOWDEFY_SECRET_TEST: 'supersecret',
|
||||
};
|
||||
const getSecrets = createGetSecretsFromEnv();
|
||||
expect(getSecrets()).toBe(getSecrets());
|
||||
});
|
||||
|
||||
test('Secrets are immutable', () => {
|
||||
process.env = {
|
||||
LOWDEFY_SECRET_TEST: 'supersecret',
|
||||
};
|
||||
const getSecrets = createGetSecretsFromEnv();
|
||||
const secrets = getSecrets();
|
||||
expect(secrets).toEqual({
|
||||
TEST: 'supersecret',
|
||||
});
|
||||
expect(() => {
|
||||
secrets.test = 'changed';
|
||||
}).toThrow(TypeError);
|
||||
});
|
@ -1,5 +1,3 @@
|
||||
const path = require('path');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
|
||||
@ -12,6 +10,7 @@ module.exports = {
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
options: {
|
||||
babelrc: false,
|
||||
presets: ['@babel/preset-react'],
|
||||
},
|
||||
},
|
||||
@ -33,13 +32,5 @@ module.exports = {
|
||||
new HtmlWebpackPlugin({
|
||||
template: './src/shell/index.html',
|
||||
}),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: 'src/server.js',
|
||||
to: '../server.js',
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
@ -3122,18 +3122,21 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@lowdefy/server@workspace:packages/server"
|
||||
dependencies:
|
||||
"@babel/cli": 7.12.1
|
||||
"@babel/core": 7.12.3
|
||||
"@babel/preset-env": 7.12.1
|
||||
"@babel/preset-react": 7.12.5
|
||||
"@lowdefy/block-tools": 1.0.2
|
||||
"@lowdefy/graphql": 0.0.0-alpha.3
|
||||
apollo-server-express: 2.19.0
|
||||
babel-jest: 26.6.3
|
||||
babel-loader: 8.2.1
|
||||
clean-webpack-plugin: 3.0.0
|
||||
copy-webpack-plugin: 6.3.0
|
||||
css-loader: 5.0.1
|
||||
express: 4.17.1
|
||||
graphql: 15.4.0
|
||||
html-webpack-plugin: 4.5.0
|
||||
jest: 26.6.3
|
||||
nodemon: 2.0.6
|
||||
react: 17.0.1
|
||||
react-dom: 17.0.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user