Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

45 Get config secrets #11

Merged
merged 6 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ENV NODE_ENV development
WORKDIR /workspace/app/

COPY controllers controllers
COPY lib lib
COPY js js
COPY views views
COPY package.json .
Expand Down
20 changes: 20 additions & 0 deletions controllers/secrets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import express from "express";
import getAllSecrets from "../js/secrets/get-all.js";
import getSecretsWithPriority from "../js/secrets/get-with-priority.js";

const router = express.Router();

router.post("/get-all", async (req, res) => {
const secrets = await getAllSecrets();
res.setHeader("Content-Type", "application/json");
return res.status(200).json({ ...secrets });
});

router.post("/get-with-priority", async (req, res) => {
const priority = req.query.priority;
const result = await getSecretsWithPriority(priority);
res.setHeader("Content-Type", "application/json");
return res.status(200).json({ ...result });
});

export default router;
30 changes: 30 additions & 0 deletions js/secrets/get-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { getAllFiles, mapSecretToJson } from "../util/utils.js";

const flattenSecrets = (data, path, result) => {
Object.keys(data).forEach((k) => {
const secretPath = path.length > 0 ? `${path}.${k}` : k;
if (typeof data[k] === "object") {
flattenSecrets(data[k], secretPath, result);
} else {
if (!result.includes(secretPath)) result.push(secretPath);
}
});
};

export default async function getAllSecrets() {
const secrets = {
prod: [],
test: [],
};
flattenSecrets(
mapSecretToJson(getAllFiles("/secrets/prod")),
"",
secrets.prod
);
flattenSecrets(
mapSecretToJson(getAllFiles("/secrets/test")),
"",
secrets.test
);
return secrets;
}
30 changes: 30 additions & 0 deletions js/secrets/get-with-priority.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { getAllFiles, mapSecretToJson } from "../util/utils.js";

export default async function getSecretsWithPriority(priority) {
const prodSecrets = mapSecretToJson(getAllFiles("/secrets/prod"));
const testSecrets = mapSecretToJson(getAllFiles("/secrets/test"));

const mergeSecrets = (secrets, result, isProdSecrets, isProdPriority) => {
Object.keys(secrets).forEach((k) => {
if (typeof secrets[k] === "object") {
if (!Object.keys(result).includes(k)) result[k] = {};
return mergeSecrets(
secrets[k],
result[k],
isProdSecrets,
isProdPriority
);
}
if (
!Object.keys(result).includes(k) ||
(!isProdSecrets && !isProdPriority)
)
result[k] = secrets[k];
});
return result;
};
const result = {};
mergeSecrets(prodSecrets, result, true, priority !== "test");
mergeSecrets(testSecrets, result, false, priority !== "test");
return result;
}
75 changes: 53 additions & 22 deletions js/util/utils.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,70 @@
import path from 'path';
import fs from 'fs';
import path from "path";
import fs from "fs";
import { parse as parseYmlToJson } from "yaml";

export const assignSecrets = (data, result) => {
Object.keys(data).forEach((k) => {
if (typeof data[k] === "object") {
result[k] = {};
return assignSecrets(data[k], result[k]);
}
result[k] = data[k];
});
};

export const mapSecretToJson = (secrets) => {
const result = {};
secrets.forEach((secretPath) => {
try {
const data = parseYmlToJson(fs.readFileSync(secretPath, "utf-8"));
assignSecrets(data, result);
} catch (_) {
return {};
}
});
return result;
};

export const buildContentFilePath = (fileName) => {
return path.join(process.env.CONTENT_FOLDER || 'data', fileName)
}
return path.join(process.env.CONTENT_FOLDER || "data", fileName);
};

export const isValidFilename = (fileName) => {
return fileName && RegExp('^[0-9a-zA-Z-._/]+$').test(fileName);
}
return fileName && RegExp("^[0-9a-zA-Z-._/]+$").test(fileName);
};

export const isValidFilePath = (filePath) => {
return filePath && isValidFilename(filePath) && path.normalize(filePath).includes('..') === false
}
return (
filePath &&
isValidFilename(filePath) &&
path.normalize(filePath).includes("..") === false
);
};

export const getAllFiles = function (dirPath) {
const folder = path.join(process.env.CONTENT_FOLDER || 'data', dirPath)
return getAllFilesInsideFolder(folder)
}
const folder = path.join(process.env.CONTENT_FOLDER || "data", dirPath);
return getAllFilesInsideFolder(folder);
};

const getAllFilesInsideFolder = function (dirPath, arrayOfFiles) {
const files = fs.readdirSync(dirPath)
arrayOfFiles = arrayOfFiles || []
const files = fs.readdirSync(dirPath);
arrayOfFiles = arrayOfFiles || [];

files.forEach(function (file) {
if (fs.statSync(dirPath + '/' + file).isDirectory()) {
arrayOfFiles = getAllFilesInsideFolder(dirPath + '/' + file, arrayOfFiles)
if (fs.statSync(dirPath + "/" + file).isDirectory()) {
arrayOfFiles = getAllFilesInsideFolder(
dirPath + "/" + file,
arrayOfFiles
);
} else {
arrayOfFiles.push(path.join(dirPath, '/', file))
arrayOfFiles.push(path.join(dirPath, "/", file));
}
})
});

return arrayOfFiles
}
return arrayOfFiles;
};

export const readFile = function (filePath) {
const data = fs.readFileSync(filePath, { encoding: 'utf8' })
return Buffer.from(data).toString()
}
const data = fs.readFileSync(filePath, { encoding: "utf8" });
return Buffer.from(data).toString();
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"express-handlebars": "^6.0.6",
"html-pdf-node": "^1.0.8",
"nodemailer": "^6.9.1",
"replace-in-file": "^6.3.5"
"replace-in-file": "^6.3.5",
"yaml": "^2.2.1"
}
}
25 changes: 16 additions & 9 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import express from "express";
import { create } from "express-handlebars";
import * as html_to_pdf from "html-pdf-node";
import secrets from "./controllers/secrets.js";
import fs from "fs";
import files from './controllers/files.js';
import files from "./controllers/files.js";
import * as helpers from "./lib/helpers.js";
import * as path from "path";
import { fileURLToPath } from "url";
Expand All @@ -13,19 +14,25 @@ const PORT = process.env.PORT || 3000;
const app = express();
const hbs = create({ helpers });
app.use(express.json());
app.use(express.urlencoded({ extended: true }))
app.use('/file-manager', files);
app.use(express.urlencoded({ extended: true }));
app.use("/file-manager", files);

app.engine("handlebars", hbs.engine);
app.set("view engine", "handlebars");
app.set("views", "./views");

app.use("/secrets", secrets);
app.get("/", (req, res) => {
res.render("home", { title: "Home" });
});

app.get("/hbs/*", (req, res) => {
res.render(req.params[0]);
app.post("/hbs/*", (req, res) => {
res.render(req.params[0], req.body, function (_, response) {
if (req.get("type") === "csv") {
res.json({ response });
} else if (req.get("type") === "json") {
res.json(JSON.parse(response));
}
});
});

app.get("/js/convert/pdf", (req, res) => {
Expand Down Expand Up @@ -58,9 +65,9 @@ app.post("/js/email/*", (req, res) => {
});

app.post("/example/post", (req, res) => {
console.log(`POST endpoint received ${JSON.stringify(req.body)}`)
res.status(200).json({ message: `received value ${req.body.name}` })
})
console.log(`POST endpoint received ${JSON.stringify(req.body)}`);
res.status(200).json({ message: `received value ${req.body.name}` });
});

app.listen(PORT, () => {
console.log("Nodejs server running on http://localhost:%s", PORT);
Expand Down