Parcourir la source

Add lesspass-cli code

Today I updated lesspass-cli on npm to fix an old issue in the counter.
https://github.com/privacytoolsIO/privacytools.io/issues/679

Add this here for memory
I will remove the folder in anoter commit
pull/478/head
Guillaume Vincent il y a 5 ans
Parent
révision
ab9c67916b
4 fichiers modifiés avec 564 ajouts et 0 suppressions
  1. +80
    -0
      packages/lesspass-cli/README.md
  2. +145
    -0
      packages/lesspass-cli/cli.js
  3. +37
    -0
      packages/lesspass-cli/package.json
  4. +302
    -0
      packages/lesspass-cli/test.js

+ 80
- 0
packages/lesspass-cli/README.md Voir le fichier

@@ -0,0 +1,80 @@
# LessPass cli

LessPass passwords directly in your terminal


## Install

```
$ npm install --global lesspass-cli
```


## Usage

```
$ lesspass --help

build LessPass passwords directly in command line

Usage
$ lesspass <site> <login> [masterPassword] [options]

Options
-l add lowercase in password
-u add uppercase in password
-d add digits in password
-s add symbols in password

--no-lowercase remove lowercase from password
--no-uppercase remove uppercase from password
--no-digits remove digits from password
--no-symbols remove symbols from password

--length, -L int (default 16)
--counter, -c int (default 1)
--clipboard, -C copy generated password to clipboard rather than displaying it.
Need pbcopy (OSX), xclip (Linux) or clip (Windows).

Examples
# no symbols
$ lesspass lesspass.com contact@lesspass.com password --no-symbols
OlfK63bmUhqrGODR
# no symbols shortcut
$ lesspass lesspass.com contact@lesspass.com password -lud
OlfK63bmUhqrGODR
# only digits and length of 8
$ lesspass lesspass.com contact@lesspass.com -d -L8
master password:
75837019
```


## FAQ

### How can I generate a password if I have a quote (`'`) in my master password ?

Escape the quote like this :

lesspass lesspass.com contact@lesspass.com 'my parents'\'' house is great'

Replace `'` by `'\''`

### password prompt

If you omit master password, lesspass-cli will ask you a master password:

lesspass lesspass.com contact@lesspass.com --length=14
master password:


## License

This project is licensed under the terms of the GNU GPLv3.

## Issues

report issues on [LessPass project](https://github.com/lesspass/lesspass/issues)

+ 145
- 0
packages/lesspass-cli/cli.js Voir le fichier

@@ -0,0 +1,145 @@
#!/usr/bin/env node
"use strict";
const clipboardy = require("clipboardy");
const meow = require("meow");
const LessPass = require("lesspass");
const read = require("read");
const chalk = require("chalk");

const helpMessage = `
Usage
$ lesspass <site> <login> [masterPassword] [options]

Options
-l add lowercase in password
-u add uppercase in password
-d add digits in password
-s add symbols in password

--no-lowercase remove lowercase from password
--no-uppercase remove uppercase from password
--no-digits remove digits from password
--no-symbols remove symbols from password

--length, -L int (default 16)
--counter, -c int (default 1)

--clipboard, -C copy generated password to clipboard rather than displaying it.
Need pbcopy (OSX), xsel (Linux) or clip (Windows).

Examples
# no symbols
$ lesspass lesspass.com contact@lesspass.com password --no-symbols
OlfK63bmUhqrGODR

# no symbols shortcut
$ lesspass lesspass.com contact@lesspass.com password -lud
OlfK63bmUhqrGODR

# only digits and length of 8
$ lesspass lesspass.com contact@lesspass.com -d -L8
master password:
75837019`;

const cli = meow(helpMessage, {
flags: {
site: { type: "string" },
login: { type: "string" },
length: {
inferType: true,
alias: "L"
},
counter: {
inferType: true,
alias: "c"
},
clipboard: {
type: "boolean",
alias: "C"
},
l: { type: "boolean" },
u: { type: "boolean" },
d: { type: "boolean" },
s: { type: "boolean" }
}
});

function calcPassword(site, login, masterPassword, passwordProfile) {
LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(
function(generatedPassword) {
if (passwordProfile.clipboard) {
clipboardy
.write(generatedPassword)
.then(() => {
console.log("Copied to clipboard");
process.exit();
})
.catch(err => {
console.error(chalk.red("Copy failed."));
console.error(err.message);
process.exit(1);
});
} else {
console.log(generatedPassword);
process.exit();
}
}
);
}

function hasNoShortOption(options) {
return !["l", "u", "d", "s"].some(function(shortOption) {
return typeof options[shortOption] !== "undefined" && options[shortOption];
});
}

function getOptionBoolean(options, optionString) {
let shortOption = optionString.substring(0, 1);
if (options[shortOption]) {
return true;
}
if (typeof options[optionString] === "undefined") {
return hasNoShortOption(options);
}
return options[optionString];
}

const lowercase = getOptionBoolean(cli.flags, "lowercase");
const uppercase = getOptionBoolean(cli.flags, "uppercase");
const symbols = getOptionBoolean(cli.flags, "symbols");
const digits = getOptionBoolean(cli.flags, "digits");

const passwordProfile = {
lowercase: lowercase,
uppercase: uppercase,
symbols: symbols,
numbers: digits,
clipboard: cli.flags.clipboard || false,
length: cli.flags.length || 16,
counter: cli.flags.counter || 1
};

const site = cli.input[0];
let login = cli.input[1];

if (typeof login === "undefined") {
login = "";
}

if (typeof site === "undefined") {
console.log(chalk.red("site cannot be empty"));
console.log("type lesspass --help");
process.exit(-1);
}

if (cli.input.length === 3) {
const masterPassword = cli.input[2];
calcPassword(site, login, masterPassword, passwordProfile);
} else {
read({ prompt: "master password: ", silent: true }, function(er, password) {
if (er && er.message === "canceled") {
process.exit();
}
calcPassword(site, login, password, passwordProfile);
});
}

+ 37
- 0
packages/lesspass-cli/package.json Voir le fichier

@@ -0,0 +1,37 @@
{
"name": "lesspass-cli",
"version": "5.2.0",
"description": "build LessPass passwords directly in command line",
"keywords": [
"cli",
"cli-app",
"lesspass",
"password"
],
"license": "GPL-3.0",
"author": "Guillaume Vincent <guillaume@oslab.fr>",
"files": [
"cli.js"
],
"bin": {
"lesspass": "cli.js"
},
"repository": "lesspass/cli",
"scripts": {
"precommit": "npm test",
"prepush": "npm test",
"test": "ava"
},
"dependencies": {
"chalk": "2.3.1",
"clipboardy": "1.2.3",
"lesspass": "9.0.0",
"meow": "4.0.0",
"read": "1.0.7"
},
"devDependencies": {
"ava": "^0.25.0",
"execa": "^0.9.0",
"husky": "^0.14.3"
}
}

+ 302
- 0
packages/lesspass-cli/test.js Voir le fichier

@@ -0,0 +1,302 @@
import test from "ava";
import execa from "execa";

test("default options", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password"
]);
t.is(stdout, "\\g-A1-.OHEwrXjT#");
});

test("no login", async t => {
return execa.shell('echo password | ./cli.js "lesspass.com"').then(result => {
t.is(result.stdout, "master password: 7Cw-APO5Co?G>W>u");
});
});

test("options can be before parameters", async t => {
const { stdout } = await execa("./cli.js", [
"-C",
"lesspass.com",
"contact@lesspass.com",
"password"
]);
t.is(stdout, "Copied to clipboard");
});

test("long options can be before parameters", async t => {
const { stdout } = await execa("./cli.js", [
"--clipboard",
"lesspass.com",
"contact@lesspass.com",
"password"
]);
t.is(stdout, "Copied to clipboard");
});

test("length", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--length=14"
]);
t.is(stdout, "=0\\A-.OHEKvwrX");
});

test("length shortcut", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-L=14"
]);
t.is(stdout, "=0\\A-.OHEKvwrX");
});

test("counter", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--counter=2"
]);
t.is(stdout, "Vf:F1'!I`8Y2`GBE");
});

test("counter shortcut", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-c=2"
]);
t.is(stdout, "Vf:F1'!I`8Y2`GBE");
});

test("counter nrt", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--counter=10"
]);
t.is(stdout, "qwv0l*n?i^Q745\\w");
});

test("no lowercase", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--no-lowercase"
]);
t.is(stdout, 'JBG\\`3{+0["(E\\JJ');
});

test("no lowercase shortcut", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-uds"
]);
t.is(stdout, 'JBG\\`3{+0["(E\\JJ');
});

test("only lowercase", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-l"
]);
t.is(stdout, "fmnujoqgcxmpffyh");
});

test("no uppercase", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--no-uppercase"
]);
t.is(stdout, 'jbg\\`3{+0["(e\\jj');
});

test("no uppercase shortcut", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-lds"
]);
t.is(stdout, 'jbg\\`3{+0["(e\\jj');
});

test("only uppercase", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-u"
]);
t.is(stdout, "FMNUJOQGCXMPFFYH");
});

test("no digits", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--no-digits"
]);
t.is(stdout, ";zkB#m]mNF$;J_Ej");
});

test("no digits shortcut", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-lus"
]);
t.is(stdout, ";zkB#m]mNF$;J_Ej");
});

test("only digits", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-d"
]);
t.is(stdout, "7587019305478072");
});

test("no symbols", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--no-symbols"
]);
t.is(stdout, "OlfK63bmUhqrGODR");
});

test("no symbols shortcut", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-lud"
]);
t.is(stdout, "OlfK63bmUhqrGODR");
});

test("only symbols", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-s"
]);
t.is(stdout, "<\"]|'`%};'`>-'[,");
});

test("test space in password", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"my Master Password"
]);
t.is(stdout, "D1PBB34\\#fh!LY={");
});

test("doc 1", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"--no-symbols"
]);
t.is(stdout, "OlfK63bmUhqrGODR");
});

test("doc 1 options before", async t => {
const { stdout } = await execa("./cli.js", [
"--no-symbols",
"lesspass.com",
"contact@lesspass.com",
"password"
]);
t.is(stdout, "OlfK63bmUhqrGODR");
});

test("doc 2", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-lud"
]);
t.is(stdout, "OlfK63bmUhqrGODR");
});

test("doc 2 options before", async t => {
const { stdout } = await execa("./cli.js", [
"-lud",
"lesspass.com",
"contact@lesspass.com",
"password"
]);
t.is(stdout, "OlfK63bmUhqrGODR");
});

test("doc 3", async t => {
const { stdout } = await execa("./cli.js", [
"lesspass.com",
"contact@lesspass.com",
"password",
"-d",
"-L8"
]);
t.is(stdout, "75837019");
});

test("doc 3 options before", async t => {
const { stdout } = await execa("./cli.js", [
"-d",
"-L8",
"lesspass.com",
"contact@lesspass.com",
"password"
]);
t.is(stdout, "75837019");
});

test("doc 3 options before and after", async t => {
const { stdout } = await execa("./cli.js", [
"-d",
"lesspass.com",
"contact@lesspass.com",
"password",
"-L8"
]);
t.is(stdout, "75837019");
});

test("nrt numbers should be considered as string not integers", async t => {
const p = execa("./cli.js", ["example.org", "123", "password"]);
const p2 = execa("./cli.js", ["example.org", "0123", "password"]);
const p3 = execa("./cli.js", ["example.org", '"0123"', "password"]);
const p4 = execa("./cli.js", ["example.org", "00123", "password"]);
return Promise.all([p, p2, p3, p4]).then(v => {
t.is(v[0].stdout, "sMb8}N&`J4wkF9q~");
t.is(v[1].stdout, "5,4SqhB2[=/h\\DZh");
t.is(v[2].stdout, "u0Fz)EOJ4i\\{{;a~");
t.is(v[3].stdout, '=}|O7hN0ZHdjQ{">');
});
});

Chargement…
Annuler
Enregistrer