dotencr
Version:
Encrypt and decrypt individual lines inside a .env file. Supports multiple encryption keys. Keys and dotenv files can be read text file or read from the environment.
214 lines • 9.49 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const dotenv_variable_1 = require("./dotenv_variable");
const lodash_1 = __importDefault(require("lodash"));
const reservedWords = __importStar(require("./reserved_words"));
/**
* Base class for the parsing of the dotenv variables
*/
class DotenvParserBase {
constructor(options) {
var _a, _b, _c, _d, _e, _f, _g;
/**
* All environment variables regardless of any errors
*/
this.variablesAll = [];
/**
* Environment variables erroneously using a reserved word for the crypto key name
*/
this.variablesUsingReservedWord = [];
/**
* List of invalid variables. Includes values using reserved words.
*/
this.variableInvalid = [];
/**
* Environment variables without any errors
*/
this.variables = [];
this.separatorLeft = (_a = options.separatorLeft) !== null && _a !== void 0 ? _a : "__";
this.minTokensLeft = (_b = options.minTokensLeft) !== null && _b !== void 0 ? _b : 2;
this.maxTokensLeft = (_c = options.maxTokensLeft) !== null && _c !== void 0 ? _c : 2;
this.separatorRight = (_d = options.separatorRight) !== null && _d !== void 0 ? _d : ".";
this.minTokensRight = (_e = options.minTokensRight) !== null && _e !== void 0 ? _e : 3;
this.maxTokensRight = (_f = options.maxTokensRight) !== null && _f !== void 0 ? _f : 3;
this.cryptoKeyNamePrefix = (_g = options.cryptoKeyNamePrefix) !== null && _g !== void 0 ? _g : "DOTENV_ENC_KEY";
}
tokenizeLeftSide(leftSide) {
// Exclude empty strings
const tokens = leftSide.split(this.separatorLeft).filter(t => !lodash_1.default.isEmpty(t));
if (tokens[0] === this.cryptoKeyNamePrefix) {
if (tokens.length < this.minTokensLeft) {
return { isValid: false, tokens };
}
if (tokens.length > this.maxTokensLeft) {
return { isValid: false, tokens };
}
return { isValid: true, tokens };
}
else {
return undefined;
}
}
tokenizeRightSide(rightSide) {
// Exclude empty strings
const tokens = rightSide.split(this.separatorRight).filter(t => !lodash_1.default.isEmpty(t));
if (tokens.length < this.minTokensRight) {
return { isValid: false, tokens };
}
if (tokens.length > this.maxTokensRight) {
return { isValid: false, tokens };
}
return { isValid: true, tokens };
}
parseObject(env) {
// Skip any pairs that do not have a value
Object.entries(env).forEach(element => {
if (element[0] && element[1]) {
const m = this.tokenize(element[0], element[1]);
if (m) {
this.variablesAll.push(m);
if (m.usingReservedWord) {
this.variablesUsingReservedWord.push(m);
}
if (m.isValid) {
this.variables.push(m);
}
else {
this.variableInvalid.push(m);
}
}
}
});
}
}
exports.DotenvParserBase = DotenvParserBase;
class DotenvParserCryptoKey extends DotenvParserBase {
constructor() {
super({
minTokensLeft: 2,
maxTokensLeft: 2,
cryptoKeyNamePrefix: "DOTENV_ENC_KEY",
});
}
tokenize(leftSide, rightSide) {
const leftTokens = this.tokenizeLeftSide(leftSide);
if (!leftTokens) {
return undefined;
}
const d = new dotenv_variable_1.DotenvVariable(leftSide, rightSide, this.separatorLeft, this.separatorRight);
d.isValid = leftTokens.isValid;
if (d.isValid) {
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.pattern, leftTokens.tokens[0]);
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.cryptoKeyName, leftTokens.tokens[1]);
if (reservedWords.keyNames.includes(d.leftCryptoKeyName())) {
d.usingReservedWord = d.leftCryptoKeyName();
d.isValid = false;
d.errors.push(`The encryption key name [${leftSide}] is the reserved word [${d.usingReservedWord}].`);
}
}
else {
d.errors.push(`The encryption key name is invalid [${leftSide}] or the value is invalid [${rightSide}].`);
}
d.errors = lodash_1.default.uniq(d.errors).sort();
return d;
}
}
exports.DotenvParserCryptoKey = DotenvParserCryptoKey;
class DotenvParserPlainTextVariable extends DotenvParserBase {
constructor() {
super({
minTokensLeft: 3,
maxTokensLeft: 3,
cryptoKeyNamePrefix: "UNENCRYPTED",
});
}
tokenize(leftSide, rightSide) {
const leftTokens = this.tokenizeLeftSide(leftSide);
if (!leftTokens) {
return undefined;
}
const d = new dotenv_variable_1.DotenvVariable(leftSide, rightSide, this.separatorLeft, this.separatorRight);
d.isValid = leftTokens.isValid;
if (d.isValid) {
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.pattern, leftTokens.tokens[0]);
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.cryptoKeyName, leftTokens.tokens[1]);
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.variableName, leftTokens.tokens[2]);
if (reservedWords.keyNamesForPlainTextVariable.includes(d.leftCryptoKeyName())) {
d.usingReservedWord = d.leftCryptoKeyName();
d.isValid = false;
d.errors.push(`The encryption key name [${leftSide}] is the reserved word [${d.usingReservedWord}].`);
}
return d;
}
else {
d.errors.push(`The encryption key name is invalid [${leftSide}] or the value is invalid [${rightSide}].`);
}
d.errors = lodash_1.default.uniq(d.errors).sort();
return d;
}
}
exports.DotenvParserPlainTextVariable = DotenvParserPlainTextVariable;
class DotenvParserCipheredVariable extends DotenvParserBase {
constructor() {
super({
minTokensLeft: 3,
maxTokensLeft: 3,
cryptoKeyNamePrefix: "CIPHERED",
});
}
tokenize(leftSide, rightSide) {
const leftTokens = this.tokenizeLeftSide(leftSide);
const rightTokens = this.tokenizeRightSide(rightSide);
if (!leftTokens) {
return undefined;
}
const d = new dotenv_variable_1.DotenvVariable(leftSide, rightSide, this.separatorLeft, this.separatorRight);
d.isValid = leftTokens.isValid && rightTokens.isValid;
if (d.isValid) {
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.pattern, leftTokens.tokens[0]);
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.cryptoKeyName, leftTokens.tokens[1]);
d.leftSideTokens.set(dotenv_variable_1.LeftSideTokenIds.variableName, leftTokens.tokens[2]);
if (reservedWords.keyNamesForCipheredVariable.includes(d.leftCryptoKeyName())) {
d.usingReservedWord = d.leftCryptoKeyName();
d.isValid = false;
d.errors.push(`The encryption key name [${leftSide}] is the reserved word [${d.usingReservedWord}].`);
}
d.rightSideTokens.set(dotenv_variable_1.RightSideTokenIds.iv, rightTokens.tokens[0]);
d.rightSideTokens.set(dotenv_variable_1.RightSideTokenIds.cipher, rightTokens.tokens[1]);
d.rightSideTokens.set(dotenv_variable_1.RightSideTokenIds.tag, rightTokens.tokens[2]);
}
else {
d.errors.push(`The encryption key name is invalid [${leftSide}] or the value is invalid [${rightSide}].`);
if (!(this.minTokensLeft <= leftTokens.tokens.length &&
leftTokens.tokens.length <= this.maxTokensLeft)) {
d.errors.push(`[${leftSide}] Got ${leftTokens.tokens.length} tokens on the left side. Expected between ${this.minTokensLeft} and ${this.maxTokensLeft}`);
}
if (!(this.minTokensRight <= rightTokens.tokens.length &&
rightTokens.tokens.length <= this.maxTokensRight)) {
d.errors.push(`[${leftSide}] Got ${rightTokens.tokens.length} tokens on the right side. Expected between ${this.minTokensRight} and ${this.maxTokensRight}`);
}
}
return d;
}
}
exports.DotenvParserCipheredVariable = DotenvParserCipheredVariable;
class DotenvParserTestConstructor extends DotenvParserBase {
constructor(options) {
super(options);
}
tokenize(_leftSide, _rightSide) {
return undefined;
}
}
exports.DotenvParserTestConstructor = DotenvParserTestConstructor;
//# sourceMappingURL=dotenv_parser.js.map