dotsec 1.0.0-alpha.2 → 1.0.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -39
- package/bin/dotsec.js +1 -1
- package/dist/cli/index.js +37 -0
- package/dist/cli/index.js.map +7 -0
- package/dist/cli/index.mjs +37 -0
- package/dist/cli/index.mjs.map +7 -0
- package/dist/index.d.ts +141 -11
- package/dist/index.js +1 -43
- package/dist/index.js.map +3 -3
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +7 -0
- package/package.json +26 -31
- package/src/templates/dotsec.config.ts +15 -0
- package/bin/ds.js +0 -3
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -2237
- package/dist/cli.js.map +0 -7
- package/dist/ds/cli.js +0 -1111
- package/dist/ds/cli.js.map +0 -7
- package/dist/esm/cli.js +0 -2245
- package/dist/esm/cli.js.map +0 -7
- package/dist/esm/ds/cli.js +0 -1116
- package/dist/esm/ds/cli.js.map +0 -7
- package/dist/esm/index.js +0 -16
- package/dist/esm/index.js.map +0 -7
package/dist/esm/ds/cli.js
DELETED
|
@@ -1,1116 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defProps = Object.defineProperties;
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
|
|
21
|
-
// src/ds/cli.ts
|
|
22
|
-
import { Command as Command2 } from "commander";
|
|
23
|
-
|
|
24
|
-
// src/ds/commands/run.ts
|
|
25
|
-
import fs from "node:fs";
|
|
26
|
-
import commander from "commander";
|
|
27
|
-
import spawn from "cross-spawn";
|
|
28
|
-
import { parse } from "dotenv";
|
|
29
|
-
|
|
30
|
-
// src/utils/getCredentialsProfileRegion.ts
|
|
31
|
-
import {
|
|
32
|
-
fromEnv,
|
|
33
|
-
fromIni,
|
|
34
|
-
fromTemporaryCredentials
|
|
35
|
-
} from "@aws-sdk/credential-providers";
|
|
36
|
-
import { loadSharedConfigFiles } from "@aws-sdk/shared-ini-file-loader";
|
|
37
|
-
|
|
38
|
-
// src/utils/logger.ts
|
|
39
|
-
import chalk from "chalk";
|
|
40
|
-
import { highlight, plain } from "cli-highlight";
|
|
41
|
-
var _logger;
|
|
42
|
-
var getLogger = () => {
|
|
43
|
-
if (!_logger) {
|
|
44
|
-
_logger = console;
|
|
45
|
-
}
|
|
46
|
-
return _logger;
|
|
47
|
-
};
|
|
48
|
-
var emphasis = (str) => chalk.yellowBright(str);
|
|
49
|
-
var strong = (str) => chalk.yellow.bold(str);
|
|
50
|
-
var myTheme = {
|
|
51
|
-
attr: chalk.yellow.bold,
|
|
52
|
-
string: chalk.yellowBright.dim,
|
|
53
|
-
params: chalk.red,
|
|
54
|
-
deletion: chalk.red.strikethrough,
|
|
55
|
-
number: plain
|
|
56
|
-
};
|
|
57
|
-
var prettyCode = (str) => {
|
|
58
|
-
return highlight(str, { theme: myTheme });
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// src/utils/getCredentialsProfileRegion.ts
|
|
62
|
-
var getCredentialsProfileRegion = async ({
|
|
63
|
-
argv,
|
|
64
|
-
env
|
|
65
|
-
}) => {
|
|
66
|
-
var _a, _b, _c;
|
|
67
|
-
const sharedConfigFiles = await loadSharedConfigFiles();
|
|
68
|
-
let credentialsAndOrigin = void 0;
|
|
69
|
-
let profileAndOrigin = void 0;
|
|
70
|
-
let regionAndOrigin = void 0;
|
|
71
|
-
if (argv.profile) {
|
|
72
|
-
profileAndOrigin = {
|
|
73
|
-
value: argv.profile,
|
|
74
|
-
origin: `command line option: ${emphasis(argv.profile)}`
|
|
75
|
-
};
|
|
76
|
-
credentialsAndOrigin = {
|
|
77
|
-
value: await fromIni({
|
|
78
|
-
profile: argv.profile
|
|
79
|
-
})(),
|
|
80
|
-
origin: `${emphasis(`[${argv.profile}]`)} in credentials file`
|
|
81
|
-
};
|
|
82
|
-
} else if (env.AWS_PROFILE) {
|
|
83
|
-
profileAndOrigin = {
|
|
84
|
-
value: env.AWS_PROFILE,
|
|
85
|
-
origin: `env variable ${emphasis("AWS_PROFILE")}: ${strong(env.AWS_PROFILE)}`
|
|
86
|
-
};
|
|
87
|
-
credentialsAndOrigin = {
|
|
88
|
-
value: await fromIni({
|
|
89
|
-
profile: env.AWS_PROFILE
|
|
90
|
-
})(),
|
|
91
|
-
origin: `env variable ${emphasis("AWS_PROFILE")}: ${strong(env.AWS_PROFILE)}`
|
|
92
|
-
};
|
|
93
|
-
} else if (env.AWS_ACCESS_KEY_ID && env.AWS_SECRET_ACCESS_KEY) {
|
|
94
|
-
credentialsAndOrigin = {
|
|
95
|
-
value: await fromEnv()(),
|
|
96
|
-
origin: `env variables ${emphasis("AWS_ACCESS_KEY_ID")} and ${emphasis("AWS_SECRET_ACCESS_KEY")}`
|
|
97
|
-
};
|
|
98
|
-
} else if ((_a = sharedConfigFiles.credentialsFile) == null ? void 0 : _a.default) {
|
|
99
|
-
profileAndOrigin = {
|
|
100
|
-
value: "default",
|
|
101
|
-
origin: `${emphasis("[default]")} in credentials file`
|
|
102
|
-
};
|
|
103
|
-
credentialsAndOrigin = {
|
|
104
|
-
value: await fromIni({
|
|
105
|
-
profile: "default"
|
|
106
|
-
})(),
|
|
107
|
-
origin: `profile ${emphasis("[default]")}`
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
if (argv.region) {
|
|
111
|
-
regionAndOrigin = {
|
|
112
|
-
value: argv.region,
|
|
113
|
-
origin: `command line option: ${emphasis(argv.region)}`
|
|
114
|
-
};
|
|
115
|
-
} else if (env.AWS_REGION) {
|
|
116
|
-
regionAndOrigin = {
|
|
117
|
-
value: env.AWS_REGION,
|
|
118
|
-
origin: `env variable ${emphasis("AWS_REGION")}: ${strong(env.AWS_REGION)}`
|
|
119
|
-
};
|
|
120
|
-
} else if (env.AWS_DEFAULT_REGION) {
|
|
121
|
-
regionAndOrigin = {
|
|
122
|
-
value: env.AWS_DEFAULT_REGION,
|
|
123
|
-
origin: `env variable ${emphasis("AWS_DEFAULT_REGION")}: ${strong(env.AWS_DEFAULT_REGION)}`
|
|
124
|
-
};
|
|
125
|
-
} else if (profileAndOrigin) {
|
|
126
|
-
const foundRegion = (_c = (_b = sharedConfigFiles == null ? void 0 : sharedConfigFiles.configFile) == null ? void 0 : _b[profileAndOrigin.value]) == null ? void 0 : _c.region;
|
|
127
|
-
if (foundRegion) {
|
|
128
|
-
regionAndOrigin = {
|
|
129
|
-
value: foundRegion,
|
|
130
|
-
origin: `${emphasis(`[profile ${profileAndOrigin.value}]`)} in config file`
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
const assumedRole = argv.assumeRoleArn || env.AWS_ASSUME_ROLE_ARN;
|
|
135
|
-
if (assumedRole) {
|
|
136
|
-
const origin = argv.assumeRoleArn ? "command line option" : "env variable";
|
|
137
|
-
credentialsAndOrigin = {
|
|
138
|
-
value: await fromTemporaryCredentials({
|
|
139
|
-
masterCredentials: credentialsAndOrigin == null ? void 0 : credentialsAndOrigin.value,
|
|
140
|
-
params: {
|
|
141
|
-
DurationSeconds: argv.assumeRoleSessionDuration || Number(env.AWS_ASSUME_ROLE_SESSION_DURATION) || 3600,
|
|
142
|
-
RoleArn: assumedRole
|
|
143
|
-
},
|
|
144
|
-
clientConfig: {
|
|
145
|
-
region: regionAndOrigin == null ? void 0 : regionAndOrigin.value
|
|
146
|
-
}
|
|
147
|
-
})(),
|
|
148
|
-
origin: `${origin} ${emphasis(`[${assumedRole}]`)}`
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
return { credentialsAndOrigin, regionAndOrigin, profileAndOrigin };
|
|
152
|
-
};
|
|
153
|
-
var printVerboseCredentialsProfileRegion = ({
|
|
154
|
-
credentialsAndOrigin,
|
|
155
|
-
regionAndOrigin,
|
|
156
|
-
profileAndOrigin
|
|
157
|
-
}) => {
|
|
158
|
-
const out = [];
|
|
159
|
-
if (profileAndOrigin) {
|
|
160
|
-
out.push(`Got profile name from ${profileAndOrigin.origin}`);
|
|
161
|
-
}
|
|
162
|
-
if (credentialsAndOrigin) {
|
|
163
|
-
out.push(`Resolved credentials from ${credentialsAndOrigin.origin}`);
|
|
164
|
-
}
|
|
165
|
-
if (regionAndOrigin) {
|
|
166
|
-
out.push(`Resolved region from ${regionAndOrigin.origin}`);
|
|
167
|
-
}
|
|
168
|
-
return out.join("\n");
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// src/lib/partial-commands/handleCredentialsAndRegion.ts
|
|
172
|
-
var handleCredentialsAndRegion = async ({
|
|
173
|
-
argv,
|
|
174
|
-
env
|
|
175
|
-
}) => {
|
|
176
|
-
const { credentialsAndOrigin, regionAndOrigin, profileAndOrigin } = await getCredentialsProfileRegion({
|
|
177
|
-
argv: {
|
|
178
|
-
region: argv.awsRegion,
|
|
179
|
-
profile: argv.awsProfile,
|
|
180
|
-
assumeRoleArn: argv.awsAssumeRoleArn,
|
|
181
|
-
assumeRoleSessionDuration: argv.awsAssumeRoleSessionDuration
|
|
182
|
-
},
|
|
183
|
-
env: __spreadValues({}, env)
|
|
184
|
-
});
|
|
185
|
-
if (argv.verbose === true) {
|
|
186
|
-
console.log(printVerboseCredentialsProfileRegion({
|
|
187
|
-
credentialsAndOrigin,
|
|
188
|
-
regionAndOrigin,
|
|
189
|
-
profileAndOrigin
|
|
190
|
-
}));
|
|
191
|
-
}
|
|
192
|
-
if (!credentialsAndOrigin || !regionAndOrigin) {
|
|
193
|
-
if (!credentialsAndOrigin) {
|
|
194
|
-
console.error("Could not find credentials");
|
|
195
|
-
throw new Error("Could not find credentials");
|
|
196
|
-
}
|
|
197
|
-
if (!regionAndOrigin) {
|
|
198
|
-
console.error("Could not find region");
|
|
199
|
-
throw new Error("Could not find region");
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return { credentialsAndOrigin, regionAndOrigin };
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
// src/lib/wtf/crypto.ts
|
|
206
|
-
import {
|
|
207
|
-
DecryptCommand,
|
|
208
|
-
DescribeKeyCommand as DescribeKeyCommand2,
|
|
209
|
-
EncryptCommand
|
|
210
|
-
} from "@aws-sdk/client-kms";
|
|
211
|
-
import {
|
|
212
|
-
CreateSecretCommand,
|
|
213
|
-
ListSecretsCommand,
|
|
214
|
-
PutSecretValueCommand
|
|
215
|
-
} from "@aws-sdk/client-secrets-manager";
|
|
216
|
-
import {
|
|
217
|
-
ParameterTier,
|
|
218
|
-
ParameterType,
|
|
219
|
-
PutParameterCommand
|
|
220
|
-
} from "@aws-sdk/client-ssm";
|
|
221
|
-
import { constantCase } from "constant-case";
|
|
222
|
-
|
|
223
|
-
// src/utils/kms.ts
|
|
224
|
-
import {
|
|
225
|
-
DescribeKeyCommand,
|
|
226
|
-
KMSClient
|
|
227
|
-
} from "@aws-sdk/client-kms";
|
|
228
|
-
var getKMSClient = ({
|
|
229
|
-
configuration
|
|
230
|
-
}) => {
|
|
231
|
-
const kmsClient = new KMSClient(configuration);
|
|
232
|
-
return kmsClient;
|
|
233
|
-
};
|
|
234
|
-
var getEncryptionAlgorithm = async (kmsClient, awsKeyAlias) => {
|
|
235
|
-
var _a, _b;
|
|
236
|
-
const describeKeyCommand = new DescribeKeyCommand({
|
|
237
|
-
KeyId: awsKeyAlias
|
|
238
|
-
});
|
|
239
|
-
const describeKeyResult = await kmsClient.send(describeKeyCommand);
|
|
240
|
-
const encryptionAlgorithm = (_b = (_a = describeKeyResult.KeyMetadata) == null ? void 0 : _a.EncryptionAlgorithms) == null ? void 0 : _b[0];
|
|
241
|
-
if (encryptionAlgorithm === void 0) {
|
|
242
|
-
throw new Error(`Could not determine encryption algorithm`);
|
|
243
|
-
}
|
|
244
|
-
return encryptionAlgorithm;
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
// src/utils/secretsManager.ts
|
|
248
|
-
import {
|
|
249
|
-
SecretsManagerClient
|
|
250
|
-
} from "@aws-sdk/client-secrets-manager";
|
|
251
|
-
|
|
252
|
-
// src/utils/ssm.ts
|
|
253
|
-
import { SSMClient } from "@aws-sdk/client-ssm";
|
|
254
|
-
|
|
255
|
-
// src/lib/wtf/types.ts
|
|
256
|
-
var isString = (value) => {
|
|
257
|
-
return typeof value === "string";
|
|
258
|
-
};
|
|
259
|
-
var isNumber = (value) => {
|
|
260
|
-
return typeof value === "number";
|
|
261
|
-
};
|
|
262
|
-
var isBoolean = (value) => {
|
|
263
|
-
return typeof value === "boolean";
|
|
264
|
-
};
|
|
265
|
-
var isSSMParameter = (leafOrTree) => {
|
|
266
|
-
const ssmParameter = leafOrTree;
|
|
267
|
-
return typeof ssmParameter === "object" && ssmParameter !== null && "type" in ssmParameter && ssmParameter.type === "ssm";
|
|
268
|
-
};
|
|
269
|
-
var isRegularParameterObject = (value) => {
|
|
270
|
-
const regularParameter = value;
|
|
271
|
-
return typeof regularParameter === "object" && regularParameter !== null && "type" in regularParameter && regularParameter.type === "standard";
|
|
272
|
-
};
|
|
273
|
-
var isRegularParameter = (leafOrTree) => {
|
|
274
|
-
const leaf = leafOrTree;
|
|
275
|
-
return isString(leaf) || isNumber(leaf) || isBoolean(leaf) || isRegularParameterObject(leaf);
|
|
276
|
-
};
|
|
277
|
-
var isEncryptedSSMParameter = (leafOrTree) => {
|
|
278
|
-
const leaf = leafOrTree;
|
|
279
|
-
return leaf.type !== void 0 && leaf.type === "ssm" && leaf.encryptedValue !== void 0;
|
|
280
|
-
};
|
|
281
|
-
var isEncryptedRegularParameter = (leafOrTree) => {
|
|
282
|
-
const leaf = leafOrTree;
|
|
283
|
-
return leaf.type !== void 0 && leaf.type === "standard" && leaf.encryptedValue !== void 0;
|
|
284
|
-
};
|
|
285
|
-
var isSecretsManagerParameter = (leafOrTree) => {
|
|
286
|
-
const leaf = leafOrTree;
|
|
287
|
-
return leaf.type !== void 0 && leaf.type === "secretsManager" && !(isString(leaf) || isNumber(leaf) || isBoolean(leaf));
|
|
288
|
-
};
|
|
289
|
-
var isDotSecTree = (leafOrTree) => {
|
|
290
|
-
if (typeof leafOrTree === "object" && !Array.isArray(leafOrTree) && leafOrTree !== null && !isSSMParameter(leafOrTree) && !isRegularParameter(leafOrTree) && !isEncryptedSSMParameter(leafOrTree) && !isEncryptedRegularParameter(leafOrTree) && !isSecretsManagerParameter(leafOrTree)) {
|
|
291
|
-
return true;
|
|
292
|
-
}
|
|
293
|
-
return false;
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
// src/lib/wtf/flat.ts
|
|
297
|
-
var flattenTree = (tree) => {
|
|
298
|
-
const lazy = {};
|
|
299
|
-
const innerParser = (leafOrTree, paths = []) => {
|
|
300
|
-
if (isDotSecTree(leafOrTree)) {
|
|
301
|
-
Object.entries(leafOrTree).map(([key, value]) => {
|
|
302
|
-
innerParser(value, [...paths, key]);
|
|
303
|
-
});
|
|
304
|
-
} else {
|
|
305
|
-
lazy[paths.join("/")] = leafOrTree;
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
innerParser(tree);
|
|
309
|
-
return lazy;
|
|
310
|
-
};
|
|
311
|
-
var flattenPlainText = (dotSec) => {
|
|
312
|
-
return __spreadProps(__spreadValues({}, dotSec), { plaintext: flattenTree(dotSec.plaintext) });
|
|
313
|
-
};
|
|
314
|
-
var flattenEncrypted = (dotSec) => {
|
|
315
|
-
return __spreadProps(__spreadValues({}, dotSec), { encrypted: flattenTree(dotSec.encrypted) });
|
|
316
|
-
};
|
|
317
|
-
var expandTree = (tree) => {
|
|
318
|
-
const lazy = {};
|
|
319
|
-
Object.entries(tree).map(([key, value]) => {
|
|
320
|
-
const paths = key.split("/");
|
|
321
|
-
let current = lazy;
|
|
322
|
-
paths.forEach((pathKey, index) => {
|
|
323
|
-
if (!current[pathKey]) {
|
|
324
|
-
if (index === paths.length - 1) {
|
|
325
|
-
current[pathKey] = value;
|
|
326
|
-
} else {
|
|
327
|
-
current[pathKey] = {};
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
current = current[pathKey];
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
return lazy;
|
|
334
|
-
};
|
|
335
|
-
var expandPlainText = (dotSec) => {
|
|
336
|
-
return __spreadProps(__spreadValues({}, dotSec), { plaintext: expandTree(dotSec.plaintext) });
|
|
337
|
-
};
|
|
338
|
-
var expandEncrypted = (dotSec) => {
|
|
339
|
-
return __spreadProps(__spreadValues({}, dotSec), { encrypted: expandTree(dotSec.encrypted) });
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
// src/lib/wtf/crypto.ts
|
|
343
|
-
var maybeJson = (value) => {
|
|
344
|
-
try {
|
|
345
|
-
return JSON.parse(value);
|
|
346
|
-
} catch (e) {
|
|
347
|
-
return value;
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
var decryptedEncrypted = async (options) => {
|
|
351
|
-
var _a, _b;
|
|
352
|
-
const { dotSecEncrypted, credentials, region, verbose, keyAlias } = options;
|
|
353
|
-
const dotSecEncryptedFlattened = flattenEncrypted(dotSecEncrypted);
|
|
354
|
-
const { info, table } = getLogger();
|
|
355
|
-
const kmsClient = getKMSClient({
|
|
356
|
-
configuration: {
|
|
357
|
-
credentials,
|
|
358
|
-
region
|
|
359
|
-
},
|
|
360
|
-
verbose
|
|
361
|
-
});
|
|
362
|
-
const awsKeyAlias = keyAlias || ((_b = (_a = dotSecEncrypted.config) == null ? void 0 : _a.aws) == null ? void 0 : _b.keyAlias);
|
|
363
|
-
if (!awsKeyAlias) {
|
|
364
|
-
throw new Error("No key alias specified");
|
|
365
|
-
}
|
|
366
|
-
if (verbose) {
|
|
367
|
-
info(`Encrypting using key alias ${emphasis(awsKeyAlias)} in ${emphasis(await kmsClient.config.region())}`);
|
|
368
|
-
const describeKeyCommand = new DescribeKeyCommand2({
|
|
369
|
-
KeyId: awsKeyAlias
|
|
370
|
-
});
|
|
371
|
-
const describeKeyResult = await kmsClient.send(describeKeyCommand);
|
|
372
|
-
info("keyMetaData", __spreadValues({}, describeKeyResult.KeyMetadata));
|
|
373
|
-
}
|
|
374
|
-
const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, awsKeyAlias);
|
|
375
|
-
const dotSecFlattened = {
|
|
376
|
-
config: __spreadValues({}, dotSecEncrypted.config),
|
|
377
|
-
plaintext: {}
|
|
378
|
-
};
|
|
379
|
-
for (const [key, encryptedValue] of Object.entries(dotSecEncryptedFlattened.encrypted)) {
|
|
380
|
-
const decryptCommand = new DecryptCommand({
|
|
381
|
-
KeyId: awsKeyAlias,
|
|
382
|
-
CiphertextBlob: Buffer.from(encryptedValue.encryptedValue, "base64"),
|
|
383
|
-
EncryptionAlgorithm: encryptionAlgorithm
|
|
384
|
-
});
|
|
385
|
-
const decryptionResult = await kmsClient.send(decryptCommand);
|
|
386
|
-
if (!decryptionResult.Plaintext) {
|
|
387
|
-
throw new Error(`Something bad happened: ${JSON.stringify({
|
|
388
|
-
key,
|
|
389
|
-
cipherText: encryptedValue,
|
|
390
|
-
decryptCommand
|
|
391
|
-
})}`);
|
|
392
|
-
}
|
|
393
|
-
if (verbose) {
|
|
394
|
-
info(`Decrypting key ${emphasis(key)} ${strong("ok")}`);
|
|
395
|
-
}
|
|
396
|
-
const decryptedValue = Buffer.from(decryptionResult.Plaintext).toString();
|
|
397
|
-
const decryptedKeyValue = JSON.parse(decryptedValue);
|
|
398
|
-
dotSecFlattened.plaintext[key] = maybeJson(decryptedKeyValue.value);
|
|
399
|
-
}
|
|
400
|
-
return expandPlainText(dotSecFlattened);
|
|
401
|
-
};
|
|
402
|
-
var encryptPlainText = async (options) => {
|
|
403
|
-
var _a, _b;
|
|
404
|
-
const { dotSecPlainText, credentials, region, verbose, keyAlias } = options;
|
|
405
|
-
const dotSecFlattened = flattenPlainText(dotSecPlainText);
|
|
406
|
-
const { info } = getLogger();
|
|
407
|
-
const kmsClient = getKMSClient({
|
|
408
|
-
configuration: {
|
|
409
|
-
credentials,
|
|
410
|
-
region
|
|
411
|
-
},
|
|
412
|
-
verbose
|
|
413
|
-
});
|
|
414
|
-
const awsKeyAlias = keyAlias || ((_b = (_a = dotSecFlattened.config) == null ? void 0 : _a.aws) == null ? void 0 : _b.keyAlias);
|
|
415
|
-
if (!awsKeyAlias) {
|
|
416
|
-
throw new Error("No key alias specified");
|
|
417
|
-
}
|
|
418
|
-
if (verbose) {
|
|
419
|
-
info(`Encrypting using key alias ${emphasis(awsKeyAlias)} in ${emphasis(await kmsClient.config.region())}`);
|
|
420
|
-
const describeKeyCommand = new DescribeKeyCommand2({
|
|
421
|
-
KeyId: awsKeyAlias
|
|
422
|
-
});
|
|
423
|
-
const describeKeyResult = await kmsClient.send(describeKeyCommand);
|
|
424
|
-
info("keyMetaData", __spreadValues({}, describeKeyResult.KeyMetadata));
|
|
425
|
-
}
|
|
426
|
-
const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, awsKeyAlias);
|
|
427
|
-
const encryptedDotSecFlattened = {
|
|
428
|
-
config: __spreadValues({}, dotSecFlattened.config),
|
|
429
|
-
encrypted: {}
|
|
430
|
-
};
|
|
431
|
-
for (const [key, plainTextValue] of Object.entries(dotSecFlattened.plaintext)) {
|
|
432
|
-
let plainTextValueCopy = plainTextValue;
|
|
433
|
-
if (typeof plainTextValueCopy !== "string" && typeof plainTextValueCopy !== "number" && typeof plainTextValueCopy !== "boolean") {
|
|
434
|
-
plainTextValueCopy = JSON.stringify(plainTextValue);
|
|
435
|
-
}
|
|
436
|
-
const damn = JSON.stringify({ key, value: plainTextValueCopy });
|
|
437
|
-
const encryptCommand = new EncryptCommand({
|
|
438
|
-
KeyId: awsKeyAlias,
|
|
439
|
-
Plaintext: Buffer.from(String(damn)),
|
|
440
|
-
EncryptionAlgorithm: encryptionAlgorithm
|
|
441
|
-
});
|
|
442
|
-
const encryptionResult = await kmsClient.send(encryptCommand);
|
|
443
|
-
if (!encryptionResult.CiphertextBlob) {
|
|
444
|
-
throw new Error(`Something bad happened: ${JSON.stringify({
|
|
445
|
-
key,
|
|
446
|
-
value: plainTextValue,
|
|
447
|
-
encryptCommand
|
|
448
|
-
})}`);
|
|
449
|
-
}
|
|
450
|
-
if (verbose) {
|
|
451
|
-
info(`Encrypting key ${emphasis(key)} ${strong("ok")}`);
|
|
452
|
-
}
|
|
453
|
-
const cipherText = Buffer.from(encryptionResult.CiphertextBlob).toString("base64");
|
|
454
|
-
if (isRegularParameter(plainTextValue)) {
|
|
455
|
-
encryptedDotSecFlattened.encrypted[key] = {
|
|
456
|
-
type: "standard",
|
|
457
|
-
encryptedValue: cipherText
|
|
458
|
-
};
|
|
459
|
-
} else if (isSSMParameter(plainTextValue)) {
|
|
460
|
-
encryptedDotSecFlattened.encrypted[key] = {
|
|
461
|
-
type: "ssm",
|
|
462
|
-
encryptedValue: cipherText
|
|
463
|
-
};
|
|
464
|
-
} else if (isSecretsManagerParameter(plainTextValue)) {
|
|
465
|
-
encryptedDotSecFlattened.encrypted[key] = {
|
|
466
|
-
type: "secretsManager",
|
|
467
|
-
encryptedValue: cipherText
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
return expandEncrypted(encryptedDotSecFlattened);
|
|
472
|
-
};
|
|
473
|
-
var decryptRawDotSecValues = async (options) => {
|
|
474
|
-
const { info } = getLogger();
|
|
475
|
-
const {
|
|
476
|
-
dotSecKeysValues: rawDotSec,
|
|
477
|
-
credentials,
|
|
478
|
-
region,
|
|
479
|
-
verbose,
|
|
480
|
-
keyAlias,
|
|
481
|
-
searchPath
|
|
482
|
-
} = options;
|
|
483
|
-
const kmsClient = getKMSClient({
|
|
484
|
-
configuration: {
|
|
485
|
-
credentials,
|
|
486
|
-
region
|
|
487
|
-
},
|
|
488
|
-
verbose
|
|
489
|
-
});
|
|
490
|
-
const s = searchPath == null ? void 0 : searchPath.split(".").map((part) => `${constantCase(part)}_`).join("");
|
|
491
|
-
const awsKeyAlias = keyAlias;
|
|
492
|
-
if (!keyAlias) {
|
|
493
|
-
throw new Error("No key alias specified");
|
|
494
|
-
}
|
|
495
|
-
const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, keyAlias);
|
|
496
|
-
const dotEnvLines = [];
|
|
497
|
-
const filtered = s ? Object.fromEntries(Object.entries(rawDotSec).filter(([key]) => key.startsWith(s)).map(([key, value]) => [key.replace(s, ""), value])) : rawDotSec;
|
|
498
|
-
for (const [key, encryptedValue] of Object.entries(filtered)) {
|
|
499
|
-
const decryptCommand = new DecryptCommand({
|
|
500
|
-
KeyId: awsKeyAlias,
|
|
501
|
-
CiphertextBlob: Buffer.from(encryptedValue, "base64"),
|
|
502
|
-
EncryptionAlgorithm: encryptionAlgorithm
|
|
503
|
-
});
|
|
504
|
-
const decryptionResult = await kmsClient.send(decryptCommand);
|
|
505
|
-
if (!decryptionResult.Plaintext) {
|
|
506
|
-
throw new Error(`Something bad happened: ${JSON.stringify({
|
|
507
|
-
key,
|
|
508
|
-
cipherText: encryptedValue,
|
|
509
|
-
decryptCommand
|
|
510
|
-
})}`);
|
|
511
|
-
}
|
|
512
|
-
if (verbose) {
|
|
513
|
-
info(`Decrypting key ${emphasis(key)} ${strong("ok")}`);
|
|
514
|
-
}
|
|
515
|
-
const decryptedValue = Buffer.from(decryptionResult.Plaintext).toString();
|
|
516
|
-
const parsedValue = JSON.parse(decryptedValue);
|
|
517
|
-
const stringOrJson = maybeJson(parsedValue.value);
|
|
518
|
-
if (isRegularParameter(stringOrJson)) {
|
|
519
|
-
if (isRegularParameterObject(stringOrJson)) {
|
|
520
|
-
dotEnvLines.push(`${key}=${JSON.stringify(stringOrJson.value)}`);
|
|
521
|
-
} else {
|
|
522
|
-
dotEnvLines.push(`${key}=${String(stringOrJson)}`);
|
|
523
|
-
}
|
|
524
|
-
} else if (isSSMParameter(stringOrJson)) {
|
|
525
|
-
dotEnvLines.push(`${key}=${JSON.stringify(stringOrJson.value)}`);
|
|
526
|
-
} else if (isSecretsManagerParameter(stringOrJson)) {
|
|
527
|
-
dotEnvLines.push(`${key}=${JSON.stringify(stringOrJson.value)}`);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
return dotEnvLines.join("\n");
|
|
531
|
-
};
|
|
532
|
-
|
|
533
|
-
// src/lib/wtf/dotenv.ts
|
|
534
|
-
import { constantCase as constantCase2 } from "constant-case";
|
|
535
|
-
var fromPlainTextLeafsToEnvEntries = (leafs) => {
|
|
536
|
-
return Object.entries(leafs).map(([key, plainTextValue]) => {
|
|
537
|
-
const parts = key.split("/");
|
|
538
|
-
const dotEnvKeyPath = parts.map((k) => constantCase2(k)).join("_");
|
|
539
|
-
let storageValue;
|
|
540
|
-
if (isRegularParameter(plainTextValue)) {
|
|
541
|
-
if (isRegularParameterObject(plainTextValue)) {
|
|
542
|
-
storageValue = plainTextValue.value;
|
|
543
|
-
} else {
|
|
544
|
-
storageValue = plainTextValue;
|
|
545
|
-
}
|
|
546
|
-
} else if (isSSMParameter(plainTextValue)) {
|
|
547
|
-
storageValue = plainTextValue.value;
|
|
548
|
-
} else if (isSecretsManagerParameter(plainTextValue)) {
|
|
549
|
-
storageValue = plainTextValue.value;
|
|
550
|
-
} else {
|
|
551
|
-
throw new Error("Invalid parameter type");
|
|
552
|
-
}
|
|
553
|
-
if (!isString(storageValue) && !isNumber(storageValue) && !isBoolean(storageValue)) {
|
|
554
|
-
storageValue = JSON.stringify(storageValue);
|
|
555
|
-
}
|
|
556
|
-
return `${dotEnvKeyPath}=${String(storageValue)}`;
|
|
557
|
-
});
|
|
558
|
-
};
|
|
559
|
-
var toDotEnv = (options) => {
|
|
560
|
-
const { info } = getLogger();
|
|
561
|
-
const { dotSecPlainText, searchPath, verbose } = options;
|
|
562
|
-
let tree = dotSecPlainText.plaintext;
|
|
563
|
-
if (searchPath) {
|
|
564
|
-
if (verbose) {
|
|
565
|
-
info(`Searching for path: ${strong(searchPath)}`);
|
|
566
|
-
}
|
|
567
|
-
const pathParts = searchPath.split("/");
|
|
568
|
-
for (const pathPart of pathParts) {
|
|
569
|
-
tree = tree[pathPart];
|
|
570
|
-
if (tree === void 0) {
|
|
571
|
-
throw new Error(`Invalid search path: '${searchPath}', part: '${pathPart}' could not be found`);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
const flattenedTree = flattenTree(tree);
|
|
576
|
-
return fromPlainTextLeafsToEnvEntries(flattenedTree).join("\n");
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
// src/ds/commands/run.ts
|
|
580
|
-
var run_default = (program2) => {
|
|
581
|
-
const subProgram = program2.command("run").description("run a command with the decrypted .sec file as environment variables: dotsec run --sec .sec command npm run start").summary(`Spawns a process with (decrypted) environment variables.
|
|
582
|
-
Works with .env, .sec, secrets.{json|yml|ts} and secrets.encrypted.{json|yml|ts}.
|
|
583
|
-
|
|
584
|
-
Examples:
|
|
585
|
-
|
|
586
|
-
// run npm start with .sec file
|
|
587
|
-
dotsec run --sec .sec command npm start
|
|
588
|
-
dotsec run command npm start
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
// run npm start with .env file
|
|
592
|
-
dotsec run --env .env command npm start
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
// run npm start with secrets.json file
|
|
596
|
-
dotsec run --secrets secrets.json command npm start
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
// run npm start with secrets.encrypted.json file
|
|
600
|
-
dotsec run --encrypted-secrets secrets.encrypted.json command npm start
|
|
601
|
-
`).option("--env <env>", "Run command with .env file").option("--sec <sec>", "Run command with .sec file").option("--secrets <secrets>", "Run command with secrets.json file").option("--encryptedSecrets,--encrypted-secrets <encryptedSecrets>", "Run command with encrypted.secrets.json file").option("--awsKeyAlias, --aws-key-alias <awsKeyAlias>").option("--awsRegion, --aws-region <awsRegion>").option("--searchPath, --search-path <searchPath>").action((_options, command) => {
|
|
602
|
-
command.help();
|
|
603
|
-
});
|
|
604
|
-
subProgram.command("command <command...>").allowUnknownOption().passThroughOptions().action(async (commands, _options, command) => {
|
|
605
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
606
|
-
const config = (_a = command.parent) == null ? void 0 : _a.getOptionValue("dotsecConfig");
|
|
607
|
-
const verbose = Boolean((_b = command.parent) == null ? void 0 : _b.getOptionValue("verbose"));
|
|
608
|
-
const awsKeyAlias = ((_c = command.parent) == null ? void 0 : _c.getOptionValue("awsKeyAlias")) || config.aws.keyAlias;
|
|
609
|
-
const awsRegion = ((_d = command.parent) == null ? void 0 : _d.getOptionValue("awsRegion")) || config.aws.region;
|
|
610
|
-
const searchPath = (_e = command.parent) == null ? void 0 : _e.getOptionValue("searchPath");
|
|
611
|
-
const sec = (_f = command.parent) == null ? void 0 : _f.getOptionValue("sec");
|
|
612
|
-
const env = (_g = command.parent) == null ? void 0 : _g.getOptionValue("env");
|
|
613
|
-
console.log("awsKeyAlias", {
|
|
614
|
-
awsRegion,
|
|
615
|
-
awsKeyAlias,
|
|
616
|
-
searchPath,
|
|
617
|
-
sec,
|
|
618
|
-
env,
|
|
619
|
-
commands
|
|
620
|
-
});
|
|
621
|
-
const inputFiles = ["env", "sec", "secrets", "encryptedSecrets"].map((fileType) => {
|
|
622
|
-
var _a2;
|
|
623
|
-
const filename = (_a2 = command.parent) == null ? void 0 : _a2.getOptionValue(fileType);
|
|
624
|
-
if (filename) {
|
|
625
|
-
return [fileType, filename];
|
|
626
|
-
}
|
|
627
|
-
}).filter((v) => !!v);
|
|
628
|
-
let rawDotenv;
|
|
629
|
-
if (inputFiles.length <= 1) {
|
|
630
|
-
try {
|
|
631
|
-
const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
|
|
632
|
-
argv: {},
|
|
633
|
-
env: __spreadValues({}, process.env)
|
|
634
|
-
});
|
|
635
|
-
const fileType = inputFiles.length === 0 ? "sec" : (_h = inputFiles[0]) == null ? void 0 : _h[0];
|
|
636
|
-
const filename = inputFiles.length === 0 ? ".sec" : (_i = inputFiles[0]) == null ? void 0 : _i[1];
|
|
637
|
-
console.log("filename", filename);
|
|
638
|
-
if (filename && fileType) {
|
|
639
|
-
const raw = fs.readFileSync(filename, "utf8");
|
|
640
|
-
if (fileType === "sec") {
|
|
641
|
-
rawDotenv = await decryptRawDotSecValues({
|
|
642
|
-
dotSecKeysValues: parse(raw),
|
|
643
|
-
credentials: credentialsAndOrigin.value,
|
|
644
|
-
region: awsRegion || regionAndOrigin.value,
|
|
645
|
-
keyAlias: awsKeyAlias,
|
|
646
|
-
verbose,
|
|
647
|
-
searchPath
|
|
648
|
-
});
|
|
649
|
-
} else if (fileType === "env") {
|
|
650
|
-
rawDotenv = raw;
|
|
651
|
-
} else if (fileType === "secrets") {
|
|
652
|
-
const dotSecPlainText = JSON.parse(raw);
|
|
653
|
-
rawDotenv = toDotEnv({
|
|
654
|
-
dotSecPlainText,
|
|
655
|
-
verbose,
|
|
656
|
-
searchPath
|
|
657
|
-
});
|
|
658
|
-
} else if (fileType === "encryptedSecrets") {
|
|
659
|
-
rawDotenv = raw;
|
|
660
|
-
const dotSecEncrypted = JSON.parse(raw);
|
|
661
|
-
const dotSecPlainText = await decryptedEncrypted({
|
|
662
|
-
dotSecEncrypted,
|
|
663
|
-
credentials: credentialsAndOrigin.value,
|
|
664
|
-
region: awsRegion || regionAndOrigin.value,
|
|
665
|
-
keyAlias: awsKeyAlias,
|
|
666
|
-
verbose
|
|
667
|
-
});
|
|
668
|
-
rawDotenv = toDotEnv({
|
|
669
|
-
dotSecPlainText,
|
|
670
|
-
verbose,
|
|
671
|
-
searchPath
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
if (rawDotenv) {
|
|
676
|
-
const [userCommand, ...userCommandArgs] = commands;
|
|
677
|
-
const parsedDotEnv = parse(rawDotenv);
|
|
678
|
-
spawn(userCommand, [...userCommandArgs], {
|
|
679
|
-
stdio: "inherit",
|
|
680
|
-
shell: false,
|
|
681
|
-
env: __spreadProps(__spreadValues(__spreadValues({}, process.env), parsedDotEnv), {
|
|
682
|
-
__DOTSEC_VARS: JSON.stringify(Object.keys(parsedDotEnv))
|
|
683
|
-
})
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
} catch (e) {
|
|
687
|
-
if (e instanceof Error) {
|
|
688
|
-
console.error(e.message);
|
|
689
|
-
if (verbose) {
|
|
690
|
-
console.error(e.name, e.stack);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
} else {
|
|
695
|
-
throw new commander.InvalidOptionArgumentError("Can only pick one of --sec. --env, --secrets or --encryptedSecrets");
|
|
696
|
-
}
|
|
697
|
-
});
|
|
698
|
-
return subProgram;
|
|
699
|
-
};
|
|
700
|
-
|
|
701
|
-
// src/ds/commands/encrypt.ts
|
|
702
|
-
import fs2 from "node:fs";
|
|
703
|
-
import path2 from "node:path";
|
|
704
|
-
|
|
705
|
-
// src/utils/io.ts
|
|
706
|
-
import { stat } from "fs/promises";
|
|
707
|
-
import prompts from "prompts";
|
|
708
|
-
import path from "node:path";
|
|
709
|
-
var fileExists = async (source) => {
|
|
710
|
-
try {
|
|
711
|
-
await stat(source);
|
|
712
|
-
return true;
|
|
713
|
-
} catch {
|
|
714
|
-
return false;
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
|
-
var promptOverwriteIfFileExists = async ({
|
|
718
|
-
filePath,
|
|
719
|
-
skip
|
|
720
|
-
}) => {
|
|
721
|
-
let overwriteResponse;
|
|
722
|
-
if (await fileExists(filePath) && skip !== true) {
|
|
723
|
-
overwriteResponse = await prompts({
|
|
724
|
-
type: "confirm",
|
|
725
|
-
name: "overwrite",
|
|
726
|
-
message: () => {
|
|
727
|
-
return `Overwrite './${path.relative(process.cwd(), filePath)}' ?`;
|
|
728
|
-
}
|
|
729
|
-
});
|
|
730
|
-
} else {
|
|
731
|
-
overwriteResponse = void 0;
|
|
732
|
-
}
|
|
733
|
-
return overwriteResponse;
|
|
734
|
-
};
|
|
735
|
-
|
|
736
|
-
// src/lib/wtf/dotsec.ts
|
|
737
|
-
import { constantCase as constantCase3 } from "constant-case";
|
|
738
|
-
var fromEncryptedLeafsToEnvEntries = (leafs) => {
|
|
739
|
-
return Object.entries(leafs).map(([key, plainTextValue]) => {
|
|
740
|
-
const parts = key.split("/");
|
|
741
|
-
const dotEnvKeyPath = parts.map((k) => constantCase3(k)).join("_");
|
|
742
|
-
let storageValue;
|
|
743
|
-
if (isEncryptedRegularParameter(plainTextValue)) {
|
|
744
|
-
storageValue = plainTextValue.encryptedValue;
|
|
745
|
-
} else if (isEncryptedSSMParameter(plainTextValue)) {
|
|
746
|
-
storageValue = plainTextValue.encryptedValue;
|
|
747
|
-
} else if (isSecretsManagerParameter(plainTextValue)) {
|
|
748
|
-
storageValue = plainTextValue.encryptedValue;
|
|
749
|
-
} else {
|
|
750
|
-
throw new Error("Invalid parameter type");
|
|
751
|
-
}
|
|
752
|
-
return `${dotEnvKeyPath}=${String(storageValue)}`;
|
|
753
|
-
});
|
|
754
|
-
};
|
|
755
|
-
var toDotSec = (options) => {
|
|
756
|
-
const { info } = getLogger();
|
|
757
|
-
const { dotSecEncrypted, searchPath, verbose } = options;
|
|
758
|
-
let tree = dotSecEncrypted.encrypted;
|
|
759
|
-
if (searchPath) {
|
|
760
|
-
if (verbose) {
|
|
761
|
-
info(`Searching for path: ${strong(searchPath)}`);
|
|
762
|
-
}
|
|
763
|
-
const pathParts = searchPath.split("/");
|
|
764
|
-
for (const pathPart of pathParts) {
|
|
765
|
-
tree = tree[pathPart];
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
const flattenedTree = flattenTree(tree);
|
|
769
|
-
return fromEncryptedLeafsToEnvEntries(flattenedTree).join("\n");
|
|
770
|
-
};
|
|
771
|
-
|
|
772
|
-
// src/ds/commands/encrypt.ts
|
|
773
|
-
var writeOut = async (options) => {
|
|
774
|
-
const { info } = getLogger();
|
|
775
|
-
const {
|
|
776
|
-
targetFile: encryptedSecretsPath,
|
|
777
|
-
converted,
|
|
778
|
-
skipPromptForOverride
|
|
779
|
-
} = options;
|
|
780
|
-
info(`target: ${strong(encryptedSecretsPath)}
|
|
781
|
-
`);
|
|
782
|
-
info(prettyCode(converted));
|
|
783
|
-
info("\n");
|
|
784
|
-
const overwriteResponse = await promptOverwriteIfFileExists({
|
|
785
|
-
filePath: encryptedSecretsPath,
|
|
786
|
-
skip: skipPromptForOverride
|
|
787
|
-
});
|
|
788
|
-
if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
|
|
789
|
-
fs2.writeFileSync(encryptedSecretsPath, converted);
|
|
790
|
-
info(`Wrote encrypted secrets to ${strong(`./${path2.relative(process.cwd(), encryptedSecretsPath)}`)}`);
|
|
791
|
-
}
|
|
792
|
-
};
|
|
793
|
-
var encrypt = async (options) => {
|
|
794
|
-
console.log("options", options);
|
|
795
|
-
const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
|
|
796
|
-
argv: {},
|
|
797
|
-
env: __spreadValues({}, process.env)
|
|
798
|
-
});
|
|
799
|
-
const {
|
|
800
|
-
secrets,
|
|
801
|
-
awsKeyAlias,
|
|
802
|
-
awsRegion,
|
|
803
|
-
verbose,
|
|
804
|
-
encryptedSecrets,
|
|
805
|
-
sec,
|
|
806
|
-
skipPromptForOverride
|
|
807
|
-
} = options;
|
|
808
|
-
const dotSecPlainText = JSON.parse(fs2.readFileSync(secrets, "utf8"));
|
|
809
|
-
const dotSecEncrypted = await encryptPlainText({
|
|
810
|
-
dotSecPlainText,
|
|
811
|
-
credentials: credentialsAndOrigin.value,
|
|
812
|
-
region: awsRegion || regionAndOrigin.value,
|
|
813
|
-
keyAlias: awsKeyAlias,
|
|
814
|
-
verbose
|
|
815
|
-
});
|
|
816
|
-
if (encryptedSecrets) {
|
|
817
|
-
const targetFile = path2.resolve(process.cwd(), encryptedSecrets);
|
|
818
|
-
const converted = JSON.stringify(dotSecEncrypted, null, 2);
|
|
819
|
-
await writeOut({
|
|
820
|
-
targetFile,
|
|
821
|
-
converted,
|
|
822
|
-
skipPromptForOverride
|
|
823
|
-
});
|
|
824
|
-
} else if (sec) {
|
|
825
|
-
const dotSec = toDotSec({
|
|
826
|
-
dotSecEncrypted,
|
|
827
|
-
verbose
|
|
828
|
-
});
|
|
829
|
-
const targetFile = path2.resolve(process.cwd(), sec);
|
|
830
|
-
await writeOut({
|
|
831
|
-
targetFile,
|
|
832
|
-
converted: dotSec,
|
|
833
|
-
skipPromptForOverride
|
|
834
|
-
});
|
|
835
|
-
} else {
|
|
836
|
-
throw new Error("Must provide either encryptedSecrets or sec");
|
|
837
|
-
}
|
|
838
|
-
};
|
|
839
|
-
var encrypt_default = (program2) => {
|
|
840
|
-
const encryptProgram = program2.enablePositionalOptions().command("encrypt").option("--secrets [secrets]", "Run command with secrets.json file", "secrets.json").option("--awsKeyAlias, --aws-key-alias [awsKeyAlias]").option("--awsRegion, --aws-region [awsRegion]").usage("encrypt [--secrets secrets.json] [to]").summary("Encrypt secrets.json file").description("Encrypts secrets.json to secrets.encrypted.json.\n1123").action(async (_options, command) => {
|
|
841
|
-
const verbose = Boolean(command.getOptionValue("verbose"));
|
|
842
|
-
const secrets = command.getOptionValue("secrets");
|
|
843
|
-
const config = command.getOptionValue("dotsecConfig");
|
|
844
|
-
const awsKeyAlias = command.getOptionValue("awsKeyAlias") || config.aws.keyAlias;
|
|
845
|
-
const awsRegion = command.getOptionValue("awsRegion") || config.aws.region;
|
|
846
|
-
await encrypt({
|
|
847
|
-
config,
|
|
848
|
-
verbose,
|
|
849
|
-
secrets,
|
|
850
|
-
awsKeyAlias,
|
|
851
|
-
awsRegion,
|
|
852
|
-
encryptedSecrets: "encrypted.secrets.json",
|
|
853
|
-
skipPromptForOverride: false
|
|
854
|
-
});
|
|
855
|
-
});
|
|
856
|
-
const toProgram = encryptProgram.command("to").usage("[--encryptedSecrets [encrypted.secrets.json]] [--sec [.sec]]").summary("specifies encryption output format").action(async (_options, command) => {
|
|
857
|
-
command.help();
|
|
858
|
-
});
|
|
859
|
-
toProgram.command("dotsec").option("--sec, [sec]", "Target dotsec file", ".sec").action(async (_options, command) => {
|
|
860
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
861
|
-
const config = (_b = (_a = command.parent) == null ? void 0 : _a.parent) == null ? void 0 : _b.getOptionValue("dotsecConfig");
|
|
862
|
-
const verbose = Boolean((_e = (_d = (_c = command.parent) == null ? void 0 : _c.parent) == null ? void 0 : _d.parent) == null ? void 0 : _e.getOptionValue("verbose"));
|
|
863
|
-
const secrets = (_g = (_f = command.parent) == null ? void 0 : _f.parent) == null ? void 0 : _g.getOptionValue("secrets");
|
|
864
|
-
const sec = command.getOptionValue("sec");
|
|
865
|
-
const awsKeyAlias = ((_j = (_i = (_h = command.parent) == null ? void 0 : _h.parent) == null ? void 0 : _i.parent) == null ? void 0 : _j.getOptionValue("awsKeyAlias")) || config.aws.keyAlias;
|
|
866
|
-
const awsRegion = ((_m = (_l = (_k = command.parent) == null ? void 0 : _k.parent) == null ? void 0 : _l.parent) == null ? void 0 : _m.getOptionValue("awsRegion")) || config.aws.region;
|
|
867
|
-
await encrypt({
|
|
868
|
-
config,
|
|
869
|
-
verbose,
|
|
870
|
-
secrets,
|
|
871
|
-
awsKeyAlias,
|
|
872
|
-
awsRegion,
|
|
873
|
-
sec,
|
|
874
|
-
skipPromptForOverride: false
|
|
875
|
-
});
|
|
876
|
-
});
|
|
877
|
-
toProgram.command("encryptedSecrets").option("--encryptedSecrets,--encrypted-secrets [encryptedSecrets]", "Target encrypted secrets file", "encrypted.secrets.json").action(async (_options, command) => {
|
|
878
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
879
|
-
const config = (_b = (_a = command.parent) == null ? void 0 : _a.parent) == null ? void 0 : _b.getOptionValue("dotsecConfig");
|
|
880
|
-
const verbose = Boolean((_e = (_d = (_c = command.parent) == null ? void 0 : _c.parent) == null ? void 0 : _d.parent) == null ? void 0 : _e.getOptionValue("verbose"));
|
|
881
|
-
const secrets = (_g = (_f = command.parent) == null ? void 0 : _f.parent) == null ? void 0 : _g.getOptionValue("secrets");
|
|
882
|
-
const encryptedSecrets = command.getOptionValue("encryptedSecrets");
|
|
883
|
-
const awsKeyAlias = ((_j = (_i = (_h = command.parent) == null ? void 0 : _h.parent) == null ? void 0 : _i.parent) == null ? void 0 : _j.getOptionValue("awsKeyAlias")) || config.aws.keyAlias;
|
|
884
|
-
const awsRegion = ((_m = (_l = (_k = command.parent) == null ? void 0 : _k.parent) == null ? void 0 : _l.parent) == null ? void 0 : _m.getOptionValue("awsRegion")) || config.aws.region;
|
|
885
|
-
await encrypt({
|
|
886
|
-
config,
|
|
887
|
-
verbose,
|
|
888
|
-
secrets,
|
|
889
|
-
awsKeyAlias,
|
|
890
|
-
awsRegion,
|
|
891
|
-
encryptedSecrets,
|
|
892
|
-
skipPromptForOverride: false
|
|
893
|
-
});
|
|
894
|
-
});
|
|
895
|
-
return encryptProgram;
|
|
896
|
-
};
|
|
897
|
-
|
|
898
|
-
// src/ds/commands/decrypt.ts
|
|
899
|
-
import fs3 from "node:fs";
|
|
900
|
-
import path3 from "node:path";
|
|
901
|
-
var writeOut2 = async (options) => {
|
|
902
|
-
const { info } = getLogger();
|
|
903
|
-
const {
|
|
904
|
-
targetFile: encryptedSecretsPath,
|
|
905
|
-
converted,
|
|
906
|
-
skipPromptForOverride
|
|
907
|
-
} = options;
|
|
908
|
-
info(`target: ${strong(encryptedSecretsPath)}
|
|
909
|
-
`);
|
|
910
|
-
info(prettyCode(converted));
|
|
911
|
-
info("\n");
|
|
912
|
-
const overwriteResponse = await promptOverwriteIfFileExists({
|
|
913
|
-
filePath: encryptedSecretsPath,
|
|
914
|
-
skip: skipPromptForOverride
|
|
915
|
-
});
|
|
916
|
-
if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
|
|
917
|
-
fs3.writeFileSync(encryptedSecretsPath, converted);
|
|
918
|
-
info(`Wrote encrypted secrets to ${strong(`./${path3.relative(process.cwd(), encryptedSecretsPath)}`)}`);
|
|
919
|
-
}
|
|
920
|
-
};
|
|
921
|
-
var decrypt = async (options) => {
|
|
922
|
-
console.log("options", options);
|
|
923
|
-
const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
|
|
924
|
-
argv: {},
|
|
925
|
-
env: __spreadValues({}, process.env)
|
|
926
|
-
});
|
|
927
|
-
const {
|
|
928
|
-
secrets,
|
|
929
|
-
awsKeyAlias,
|
|
930
|
-
awsRegion,
|
|
931
|
-
verbose,
|
|
932
|
-
encryptedSecrets,
|
|
933
|
-
sec,
|
|
934
|
-
skipPromptForOverride
|
|
935
|
-
} = options;
|
|
936
|
-
const dotSecPlainText = JSON.parse(fs3.readFileSync(secrets, "utf8"));
|
|
937
|
-
const dotSecEncrypted = await encryptPlainText({
|
|
938
|
-
dotSecPlainText,
|
|
939
|
-
credentials: credentialsAndOrigin.value,
|
|
940
|
-
region: awsRegion || regionAndOrigin.value,
|
|
941
|
-
keyAlias: awsKeyAlias,
|
|
942
|
-
verbose
|
|
943
|
-
});
|
|
944
|
-
if (encryptedSecrets) {
|
|
945
|
-
const targetFile = path3.resolve(process.cwd(), encryptedSecrets);
|
|
946
|
-
const converted = JSON.stringify(dotSecEncrypted, null, 2);
|
|
947
|
-
await writeOut2({
|
|
948
|
-
targetFile,
|
|
949
|
-
converted,
|
|
950
|
-
skipPromptForOverride
|
|
951
|
-
});
|
|
952
|
-
} else if (sec) {
|
|
953
|
-
const dotSec = toDotSec({
|
|
954
|
-
dotSecEncrypted,
|
|
955
|
-
verbose
|
|
956
|
-
});
|
|
957
|
-
const targetFile = path3.resolve(process.cwd(), sec);
|
|
958
|
-
await writeOut2({
|
|
959
|
-
targetFile,
|
|
960
|
-
converted: dotSec,
|
|
961
|
-
skipPromptForOverride
|
|
962
|
-
});
|
|
963
|
-
} else {
|
|
964
|
-
throw new Error("Must provide either encryptedSecrets or sec");
|
|
965
|
-
}
|
|
966
|
-
};
|
|
967
|
-
var decrypt_default = (program2) => {
|
|
968
|
-
const encryptProgram = program2.enablePositionalOptions().command("decrypt").option("--secrets [secrets]", "Run command with secrets.json file", "secrets.json").option("--awsKeyAlias, --aws-key-alias [awsKeyAlias]").option("--awsRegion, --aws-region [awsRegion]").usage("encrypt [--secrets secrets.json] [to]").summary("Encrypt secrets.json file").description("Encrypts secrets.json to secrets.encrypted.json.\n1123").action(async (_options, command) => {
|
|
969
|
-
const verbose = Boolean(command.getOptionValue("verbose"));
|
|
970
|
-
const secrets = command.getOptionValue("secrets");
|
|
971
|
-
const config = command.getOptionValue("dotsecConfig");
|
|
972
|
-
const awsKeyAlias = command.getOptionValue("awsKeyAlias") || config.aws.keyAlias;
|
|
973
|
-
const awsRegion = command.getOptionValue("awsRegion") || config.aws.region;
|
|
974
|
-
await decrypt({
|
|
975
|
-
config,
|
|
976
|
-
verbose,
|
|
977
|
-
secrets,
|
|
978
|
-
awsKeyAlias,
|
|
979
|
-
awsRegion,
|
|
980
|
-
encryptedSecrets: "encrypted.secrets.json",
|
|
981
|
-
skipPromptForOverride: false
|
|
982
|
-
});
|
|
983
|
-
});
|
|
984
|
-
const toProgram = encryptProgram.command("to").usage("[--encryptedSecrets [encrypted.secrets.json]] [--sec [.sec]]").summary("specifies encryption output format").action(async (_options, command) => {
|
|
985
|
-
command.help();
|
|
986
|
-
});
|
|
987
|
-
toProgram.command("dotsec").option("--sec, [sec]", "Target dotsec file", ".sec").action(async (_options, command) => {
|
|
988
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
989
|
-
const config = (_b = (_a = command.parent) == null ? void 0 : _a.parent) == null ? void 0 : _b.getOptionValue("dotsecConfig");
|
|
990
|
-
const verbose = Boolean((_e = (_d = (_c = command.parent) == null ? void 0 : _c.parent) == null ? void 0 : _d.parent) == null ? void 0 : _e.getOptionValue("verbose"));
|
|
991
|
-
const secrets = (_g = (_f = command.parent) == null ? void 0 : _f.parent) == null ? void 0 : _g.getOptionValue("secrets");
|
|
992
|
-
const sec = command.getOptionValue("sec");
|
|
993
|
-
const awsKeyAlias = ((_j = (_i = (_h = command.parent) == null ? void 0 : _h.parent) == null ? void 0 : _i.parent) == null ? void 0 : _j.getOptionValue("awsKeyAlias")) || config.aws.keyAlias;
|
|
994
|
-
const awsRegion = ((_m = (_l = (_k = command.parent) == null ? void 0 : _k.parent) == null ? void 0 : _l.parent) == null ? void 0 : _m.getOptionValue("awsRegion")) || config.aws.region;
|
|
995
|
-
await decrypt({
|
|
996
|
-
config,
|
|
997
|
-
verbose,
|
|
998
|
-
secrets,
|
|
999
|
-
awsKeyAlias,
|
|
1000
|
-
awsRegion,
|
|
1001
|
-
sec,
|
|
1002
|
-
skipPromptForOverride: false
|
|
1003
|
-
});
|
|
1004
|
-
});
|
|
1005
|
-
toProgram.command("encryptedSecrets").option("--encryptedSecrets,--encrypted-secrets [encryptedSecrets]", "Target encrypted secrets file", "encrypted.secrets.json").action(async (_options, command) => {
|
|
1006
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
1007
|
-
const config = (_b = (_a = command.parent) == null ? void 0 : _a.parent) == null ? void 0 : _b.getOptionValue("dotsecConfig");
|
|
1008
|
-
const verbose = Boolean((_e = (_d = (_c = command.parent) == null ? void 0 : _c.parent) == null ? void 0 : _d.parent) == null ? void 0 : _e.getOptionValue("verbose"));
|
|
1009
|
-
const secrets = (_g = (_f = command.parent) == null ? void 0 : _f.parent) == null ? void 0 : _g.getOptionValue("secrets");
|
|
1010
|
-
const encryptedSecrets = command.getOptionValue("encryptedSecrets");
|
|
1011
|
-
const awsKeyAlias = ((_j = (_i = (_h = command.parent) == null ? void 0 : _h.parent) == null ? void 0 : _i.parent) == null ? void 0 : _j.getOptionValue("awsKeyAlias")) || config.aws.keyAlias;
|
|
1012
|
-
const awsRegion = ((_m = (_l = (_k = command.parent) == null ? void 0 : _k.parent) == null ? void 0 : _l.parent) == null ? void 0 : _m.getOptionValue("awsRegion")) || config.aws.region;
|
|
1013
|
-
await decrypt({
|
|
1014
|
-
config,
|
|
1015
|
-
verbose,
|
|
1016
|
-
secrets,
|
|
1017
|
-
awsKeyAlias,
|
|
1018
|
-
awsRegion,
|
|
1019
|
-
encryptedSecrets,
|
|
1020
|
-
skipPromptForOverride: false
|
|
1021
|
-
});
|
|
1022
|
-
});
|
|
1023
|
-
return encryptProgram;
|
|
1024
|
-
};
|
|
1025
|
-
|
|
1026
|
-
// src/lib/config/index.ts
|
|
1027
|
-
import path5 from "node:path";
|
|
1028
|
-
import { bundleRequire } from "bundle-require";
|
|
1029
|
-
import JoyCon from "joycon";
|
|
1030
|
-
|
|
1031
|
-
// src/lib/json.ts
|
|
1032
|
-
import fs4 from "fs";
|
|
1033
|
-
import path4 from "node:path";
|
|
1034
|
-
function jsoncParse(data) {
|
|
1035
|
-
try {
|
|
1036
|
-
return new Function("return " + data.trim())();
|
|
1037
|
-
} catch {
|
|
1038
|
-
return {};
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
var loadJson = async (filepath) => {
|
|
1042
|
-
try {
|
|
1043
|
-
return jsoncParse(await fs4.promises.readFile(filepath, "utf8"));
|
|
1044
|
-
} catch (error) {
|
|
1045
|
-
if (error instanceof Error) {
|
|
1046
|
-
throw new Error(`Failed to parse ${path4.relative(process.cwd(), filepath)}: ${error.message}`);
|
|
1047
|
-
} else {
|
|
1048
|
-
throw error;
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
};
|
|
1052
|
-
|
|
1053
|
-
// src/lib/config/constants.ts
|
|
1054
|
-
var defaultConfig = {
|
|
1055
|
-
aws: {
|
|
1056
|
-
keyAlias: "alias/top-secret"
|
|
1057
|
-
}
|
|
1058
|
-
};
|
|
1059
|
-
|
|
1060
|
-
// src/lib/config/index.ts
|
|
1061
|
-
var getConfig = async (filename) => {
|
|
1062
|
-
const cwd = process.cwd();
|
|
1063
|
-
const configJoycon = new JoyCon();
|
|
1064
|
-
const configPath = await configJoycon.resolve({
|
|
1065
|
-
files: filename ? [filename] : [
|
|
1066
|
-
"dotsec.config.ts",
|
|
1067
|
-
"dotsec.config.js",
|
|
1068
|
-
"dotsec.config.cjs",
|
|
1069
|
-
"dotsec.config.mjs",
|
|
1070
|
-
"dotsec.config.json",
|
|
1071
|
-
"package.json"
|
|
1072
|
-
],
|
|
1073
|
-
cwd,
|
|
1074
|
-
stopDir: path5.parse(cwd).root,
|
|
1075
|
-
packageKey: "dotsec"
|
|
1076
|
-
});
|
|
1077
|
-
if (filename && configPath === null) {
|
|
1078
|
-
throw new Error(`Could not find config file ${filename}`);
|
|
1079
|
-
}
|
|
1080
|
-
if (configPath) {
|
|
1081
|
-
if (configPath.endsWith(".json")) {
|
|
1082
|
-
const rawData = await loadJson(configPath);
|
|
1083
|
-
let data;
|
|
1084
|
-
if (configPath.endsWith("package.json") && rawData.dotsec !== void 0) {
|
|
1085
|
-
data = rawData.dotsec;
|
|
1086
|
-
} else {
|
|
1087
|
-
data = rawData;
|
|
1088
|
-
}
|
|
1089
|
-
return __spreadProps(__spreadValues(__spreadValues({}, defaultConfig), data), {
|
|
1090
|
-
aws: __spreadValues(__spreadValues({}, defaultConfig.aws), data.aws)
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
const config = await bundleRequire({
|
|
1094
|
-
filepath: configPath
|
|
1095
|
-
});
|
|
1096
|
-
const retrievedConfig = config.mod.dotsec || config.mod.default || config.mod;
|
|
1097
|
-
return __spreadValues(__spreadValues({}, defaultConfig), retrievedConfig);
|
|
1098
|
-
}
|
|
1099
|
-
return __spreadValues({}, defaultConfig);
|
|
1100
|
-
};
|
|
1101
|
-
|
|
1102
|
-
// src/ds/cli.ts
|
|
1103
|
-
var program = new Command2();
|
|
1104
|
-
program.name("dotsec").description(".env, but secure").version("1.0.0").enablePositionalOptions().option("--verbose").option("--config, <dotsec config file>").action((_options, other) => {
|
|
1105
|
-
other.help();
|
|
1106
|
-
}).hook("preSubcommand", async (thisCommand, actionCommand) => {
|
|
1107
|
-
const configfile = thisCommand.getOptionValue("config");
|
|
1108
|
-
const dotsecConfig = await getConfig(configfile);
|
|
1109
|
-
actionCommand.setOptionValue("dotsecConfig", dotsecConfig);
|
|
1110
|
-
actionCommand.setOptionValue("verbose", Boolean(thisCommand.getOptionValue("verbose")));
|
|
1111
|
-
});
|
|
1112
|
-
run_default(program);
|
|
1113
|
-
encrypt_default(program);
|
|
1114
|
-
decrypt_default(program);
|
|
1115
|
-
program.parse();
|
|
1116
|
-
//# sourceMappingURL=cli.js.map
|