Skip to content

Instantly share code, notes, and snippets.

@rbndelrio
Last active April 5, 2018 15:12
Show Gist options
  • Save rbndelrio/22798abfd5248e3418b167797917c53c to your computer and use it in GitHub Desktop.
Save rbndelrio/22798abfd5248e3418b167797917c53c to your computer and use it in GitHub Desktop.
1Password thing
#!/usr/bin/env node
const fs = require('fs');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const args = process.argv.slice(2);
const pwd = process.env['PWD'];
const project = require(pwd + '/package.json').project || {};
const clientCode = project.code;
const credGroups = project.environment;
const firstArg = args[0] || null;
const jsonInput = JSON.parse(firstArg);
const pathLegit = code => pwd.toLowerCase().indexOf(code.toLowerCase()) > -1;
const jsonCache = {}
const getJson = async (name, vault) => {
// TODO: Add support for piping/inputting JSON via command line
const vaultName = vault || 'Development Keys'
const command = name
? `op get item "${name}" --vault="${vaultName}"`
: `echo "well this is going badly"`;
if (jsonCache[vaultName]) {
if (jsonCache[vaultName][name]) {
console.info('Geting\x1b[1m\x1b[36m', name + '\x1b[0m from \x1b[1mCache\x1b[0m...')
return jsonCache[vaultName][name];
}
} else {
jsonCache[vaultName] = {}
}
console.info('Geting\x1b[1m\x1b[36m', name + '\x1b[0m from \x1b[1m' + vaultName + '\x1b[0m...')
try {
const { stdout, stderr } = await exec(command);
const json = JSON.parse(stdout);
if (stderr || !json) {
console.log(stderr)
}
jsonCache[vaultName][name] = json;
return json;
}
catch (error) {
console.error(`Something went awry: \n\x1b[31m`, error.message + '\x1b[0m');
console.log("Make sure you're logged in:\n\x1b[1meval $(op signin fiwi_keys)\x1b[0m")
process.exit(1);
return false;
}
}
const getCreds = async () => {
let envFile = "\n";
if (credGroups.length) {
console.info('Syncing 1Password Secrets');
}
for (const { name, vault, contents } of credGroups) {
const json = await getJson(name, vault);
if (!json || !json.details) return false;
const envFromCredArray = (prev, cur) => {
const matchedCredentials = contents.find(
contentItem => cur.title === contentItem.cred_name
);
if (matchedCredentials) {
const prefix = matchedCredentials.env_name;
const credFields = cur.fields;
console.log(`${prefix}`)
const envCreds = credFields.map(
({ t: title, v: value }) => `${prefix}_${title.toUpperCase()}: ${value}\n`
);
const envGroup = envCreds.join("");
return prev + envGroup + "\n";
}
return prev;
};
const jsonCreds = json.details.sections;
envFile += jsonCreds.reduce(envFromCredArray, "");
}
return envFile;
}
/*
(test -f .env && sed '/1Password/q' .env || echo '# 1Password') > .env.test && \
node pw.js >> .env.test && mv .env.test .env
*/
const getCleanEnv = async file => {
const fileName = file || '.env';
const defaultOutput = '# 1password \n';
if (fs.existsSync(fileName)) {
const envFile = await readFile(fileName, "utf8") || '';
const onePasswordRegex = /# ?1Password/;
const envTest = onePasswordRegex.exec(envFile);
const cleanIndex = envTest && envTest.length
? envTest.index + envTest[0].length
: 0;
if (cleanIndex) {
console.info(`Removing old credentials under 1Password comment block`)
return envFile.slice(0, cleanIndex);
} else {
console.info(`Wiping ${fileName}`)
return defaultOutput;
}
}
return defaultOutput;
}
const writeToEnv = async file => {
const fileName = file || '.env';
try {
const envFile = await getCreds();
const envPrefix = await getCleanEnv('.env');
const fullEnv = envPrefix + envFile;
console.info(`Pushing new creds to ${fileName}`);
const writtenFile = await writeFile(fileName, fullEnv, 'utf8');
console.log('\x1b[1m\u001b[32mSynced!\u001b[0m')
return process.exit(0);
}
catch (error) {
console.error('Shh bby is okay\n', new Error(error))
return process.exit(1);
}
}
if (!clientCode || !pathLegit(clientCode)) {
console.error(`Client code not found in current path!\n\x1b[1m\x1b[36m${clientCode} \x1b[0m\x1b[1m– ${pwd}`);
// console.log(`https://youtu.be/jl17CYYSzUw?cc_load_policy=1&t=1m26s`);
return process.exit(1);
}
writeToEnv();
{"name": "1password_thing", "version": "0.0.0", "bin": "./openv.js"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment