Created
March 11, 2020 18:12
Index file for Oclif CLI tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Command, flags} from '@oclif/command' | |
import * as inquirer from 'inquirer'; | |
import * as fs from 'fs'; | |
import cli from 'cli-ux'; | |
import { createCipheriv, randomBytes, scryptSync } from 'crypto'; | |
class Crypto extends Command { | |
static description = 'describe the command here' | |
static flags = { | |
// add --version flag to show CLI version | |
version: flags.version({char: 'v'}), | |
help: flags.help({char: 'h'}), | |
// flag with a value (-n, --name=VALUE) | |
name: flags.string({char: 'n', description: 'name to print'}), | |
// flag with no value (-f, --force) | |
force: flags.boolean({char: 'f'}), | |
// Our new input flags | |
input: flags.string({ default: '' }), | |
algorithm: flags.string({ | |
options: ['aes-192-cbc', 'aes-256-cbc', 'des-ede3'] | |
}), | |
password: flags.string({}), | |
}; | |
static args = [ | |
// Our new input arguments | |
{name: 'input'}, | |
{name: 'algorithm'}, | |
{name: 'password'} | |
]; | |
async run() { | |
// Pulls args and flags variables from Crypto class | |
const {args, flags} = this.parse(Crypto) | |
// Destructure flags object to get input and algorithm | |
let { input, algorithm, password } = flags; | |
// If input variable is undefined... | |
if (!input) { | |
// cli-ux and 'cli' object provide utilities to interact | |
// with the Oclif API. | |
input = await cli.prompt('String to be encrypted'); | |
} | |
// If algorithm variable is undefined... | |
if (!algorithm) { | |
// inquirer is an add-on for Oclif that allows us to | |
// take different kinds of input - in this case a list | |
const select = await inquirer.prompt([{ | |
name: 'algorithm', | |
message: 'Select encryption algorithm', | |
type: 'list', | |
choices: [ | |
{ name: 'aes-192-cbc' }, | |
{ name: 'aes-256-cbc' }, | |
{ name: 'des-ede3' }, | |
], | |
}]); | |
// Assign user input to algorithm variable | |
algorithm = select.algorithm; | |
} | |
// If password is undefined... | |
if (!password) { | |
password = await cli.prompt('Password for encryption key'); | |
} | |
// Encryption key length is dependent on algorithm | |
let keyLength: number; | |
switch(algorithm) { | |
case "aes-192-cbc": | |
keyLength = 24; | |
break; | |
case "aes-256-cbc": | |
keyLength = 32; | |
break; | |
case "des-ede3-cbc": | |
keyLength = 7; | |
break; | |
default: | |
keyLength = 24; | |
break; | |
} | |
// Generate encryption key from password and keyLength | |
const key = scryptSync(password ? password : 'password', 'salt', keyLength); | |
// Define IV (Initialization vector) | |
const iv = Buffer.alloc(16, 0); | |
// Create Cipher object | |
const cipher = createCipheriv( | |
algorithm ? algorithm : 'aes-192-cbc', | |
key, | |
// des-ede3 algorithm does not use iv | |
algorithm === 'des-ede3' ? '' : iv | |
); | |
this.log(`\n// Input string: ${input}`); | |
this.log(`// Algorithm: ${algorithm}`); | |
this.log(`// Cipher password: ${password}\n`); | |
let encrypted: string = cipher.update(input, 'utf8', 'hex'); | |
encrypted += cipher.final('hex'); | |
this.log(`OUTPUT: ${encrypted}`); | |
} | |
} | |
export = Crypto |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment