You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

146 lines
3.9 KiB

  1. #!/usr/bin/env node
  2. "use strict";
  3. const clipboardy = require("clipboardy");
  4. const meow = require("meow");
  5. const LessPass = require("lesspass");
  6. const read = require("read");
  7. const chalk = require("chalk");
  8. const helpMessage = `
  9. Usage
  10. $ lesspass <site> <login> [masterPassword] [options]
  11. Options
  12. -l add lowercase in password
  13. -u add uppercase in password
  14. -d add digits in password
  15. -s add symbols in password
  16. --no-lowercase remove lowercase from password
  17. --no-uppercase remove uppercase from password
  18. --no-digits remove digits from password
  19. --no-symbols remove symbols from password
  20. --length, -L int (default 16)
  21. --counter, -c int (default 1)
  22. --clipboard, -C copy generated password to clipboard rather than displaying it.
  23. Need pbcopy (OSX), xsel (Linux) or clip (Windows).
  24. Examples
  25. # no symbols
  26. $ lesspass lesspass.com contact@lesspass.com password --no-symbols
  27. OlfK63bmUhqrGODR
  28. # no symbols shortcut
  29. $ lesspass lesspass.com contact@lesspass.com password -lud
  30. OlfK63bmUhqrGODR
  31. # only digits and length of 8
  32. $ lesspass lesspass.com contact@lesspass.com -d -L8
  33. master password:
  34. 75837019`;
  35. const cli = meow(helpMessage, {
  36. flags: {
  37. site: { type: "string" },
  38. login: { type: "string" },
  39. length: {
  40. type: "string",
  41. alias: "L"
  42. },
  43. counter: {
  44. type: "string",
  45. alias: "c"
  46. },
  47. clipboard: {
  48. type: "boolean",
  49. alias: "C"
  50. },
  51. l: { type: "boolean" },
  52. u: { type: "boolean" },
  53. d: { type: "boolean" },
  54. s: { type: "boolean" }
  55. }
  56. });
  57. function calcPassword(site, login, masterPassword, passwordProfile) {
  58. LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(
  59. function(generatedPassword) {
  60. if (passwordProfile.clipboard) {
  61. clipboardy
  62. .write(generatedPassword)
  63. .then(() => {
  64. console.log("Copied to clipboard");
  65. process.exit();
  66. })
  67. .catch(err => {
  68. console.error(chalk.red("Copy failed."));
  69. console.error(err.message);
  70. process.exit(1);
  71. });
  72. } else {
  73. console.log(generatedPassword);
  74. process.exit();
  75. }
  76. }
  77. );
  78. }
  79. function hasNoShortOption(options) {
  80. return !["l", "u", "d", "s"].some(function(shortOption) {
  81. return typeof options[shortOption] !== "undefined" && options[shortOption];
  82. });
  83. }
  84. function getOptionBoolean(options, optionString) {
  85. let shortOption = optionString.substring(0, 1);
  86. if (options[shortOption]) {
  87. return true;
  88. }
  89. if (typeof options[optionString] === "undefined") {
  90. return hasNoShortOption(options);
  91. }
  92. return options[optionString];
  93. }
  94. const lowercase = getOptionBoolean(cli.flags, "lowercase");
  95. const uppercase = getOptionBoolean(cli.flags, "uppercase");
  96. const symbols = getOptionBoolean(cli.flags, "symbols");
  97. const digits = getOptionBoolean(cli.flags, "digits");
  98. const passwordProfile = {
  99. lowercase: lowercase,
  100. uppercase: uppercase,
  101. symbols: symbols,
  102. numbers: digits,
  103. clipboard: cli.flags.clipboard || false,
  104. length: cli.flags.length || 16,
  105. counter: cli.flags.counter || 1
  106. };
  107. const site = cli.input[0];
  108. let login = cli.input[1];
  109. if (typeof login === "undefined") {
  110. login = "";
  111. }
  112. if (typeof site === "undefined") {
  113. console.log(chalk.red("site cannot be empty"));
  114. console.log("type lesspass --help");
  115. process.exit(-1);
  116. }
  117. if (cli.input.length === 3) {
  118. const masterPassword = cli.input[2];
  119. calcPassword(site, login, masterPassword, passwordProfile);
  120. } else {
  121. read({ prompt: "master password: ", silent: true }, function(er, password) {
  122. if (er && er.message === "canceled") {
  123. process.exit();
  124. }
  125. calcPassword(site, login, password, passwordProfile);
  126. });
  127. }