secrez 1.1.1 → 1.1.2

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.
Files changed (68) hide show
  1. package/README.md +414 -291
  2. package/bin/secrez.js +50 -47
  3. package/coverage.report +63 -305
  4. package/package.json +10 -12
  5. package/src/Command.js +78 -57
  6. package/src/PreCommand.js +74 -70
  7. package/src/Welcome.js +144 -134
  8. package/src/cliConfig.js +14 -14
  9. package/src/commands/Alias.js +123 -100
  10. package/src/commands/Bash.js +10 -12
  11. package/src/commands/Cat.js +117 -107
  12. package/src/commands/Cd.js +39 -42
  13. package/src/commands/Chat.js +75 -63
  14. package/src/commands/Conf.js +123 -99
  15. package/src/commands/Contacts.js +189 -171
  16. package/src/commands/Copy.js +132 -113
  17. package/src/commands/Courier.js +123 -105
  18. package/src/commands/Ds.js +88 -76
  19. package/src/commands/Edit.js +122 -103
  20. package/src/commands/Export.js +153 -114
  21. package/src/commands/Find.js +115 -110
  22. package/src/commands/Help.js +20 -23
  23. package/src/commands/Import.js +296 -225
  24. package/src/commands/Lcat.js +36 -39
  25. package/src/commands/Lcd.js +38 -39
  26. package/src/commands/Lls.js +58 -55
  27. package/src/commands/Lpwd.js +20 -24
  28. package/src/commands/Ls.js +107 -97
  29. package/src/commands/Mkdir.js +35 -38
  30. package/src/commands/Mv.js +147 -114
  31. package/src/commands/Paste.js +68 -65
  32. package/src/commands/Pwd.js +18 -23
  33. package/src/commands/Quit.js +22 -24
  34. package/src/commands/Rm.js +78 -70
  35. package/src/commands/Shell.js +31 -32
  36. package/src/commands/Ssh.js +77 -63
  37. package/src/commands/Tag.js +133 -112
  38. package/src/commands/Totp.js +166 -136
  39. package/src/commands/Touch.js +169 -56
  40. package/src/commands/Use.js +44 -41
  41. package/src/commands/Ver.js +16 -18
  42. package/src/commands/Whoami.js +34 -37
  43. package/src/commands/chat/Contacts.js +41 -44
  44. package/src/commands/chat/Help.js +20 -23
  45. package/src/commands/chat/Join.js +59 -55
  46. package/src/commands/chat/Leave.js +16 -22
  47. package/src/commands/chat/Quit.js +19 -24
  48. package/src/commands/chat/Send.js +58 -57
  49. package/src/commands/chat/Show.js +60 -51
  50. package/src/commands/chat/Whoami.js +18 -22
  51. package/src/commands/index.js +20 -22
  52. package/src/index.js +3 -3
  53. package/src/prompts/ChatPrompt.js +87 -82
  54. package/src/prompts/ChatPromptMock.js +11 -17
  55. package/src/prompts/CommandPrompt.js +146 -138
  56. package/src/prompts/Completion.js +64 -69
  57. package/src/prompts/MainPrompt.js +84 -77
  58. package/src/prompts/MainPromptMock.js +19 -30
  59. package/src/prompts/MultiEditorPrompt.js +21 -22
  60. package/src/prompts/SigintManager.js +21 -24
  61. package/src/utils/AliasManager.js +16 -18
  62. package/src/utils/ContactManager.js +15 -17
  63. package/src/utils/Fido2Client.js +59 -49
  64. package/src/utils/HelpProto.js +130 -117
  65. package/src/utils/Logger.js +48 -50
  66. package/.eslintignore +0 -0
  67. package/.eslintrc +0 -33
  68. package/.jshintrc +0 -3
@@ -1,47 +1,45 @@
1
- const utils = require('@secrez/utils')
2
-
3
- class Quit extends require('../Command') {
1
+ const utils = require("@secrez/utils");
4
2
 
3
+ class Quit extends require("../Command") {
5
4
  setHelpAndCompletion() {
6
5
  this.cliConfig.completion.quit = utils.sortKeys({
7
6
  // dontSaveHistory: TRUE // not supported, yet
8
- })
9
- this.cliConfig.completion.help.quit = true
7
+ });
8
+ this.cliConfig.completion.help.quit = true;
10
9
  this.optionDefinitions = [
11
10
  {
12
- name: 'help',
13
- alias: 'h',
14
- type: Boolean
15
- }]
11
+ name: "help",
12
+ alias: "h",
13
+ type: Boolean,
14
+ },
15
+ ];
16
16
  }
17
17
 
18
18
  help() {
19
19
  return {
20
- description: ['Quits Secrez.'],
21
- examples: [
22
- 'quit'
23
- ]
24
- }
20
+ description: ["Quits Secrez."],
21
+ examples: ["quit"],
22
+ };
25
23
  }
26
24
 
27
25
  async exec(options = {}) {
28
26
  if (options.help) {
29
- return this.showHelp()
27
+ return this.showHelp();
30
28
  }
31
29
  /* istanbul ignore if */
32
30
  // eslint-disable-next-line no-constant-condition
33
- if (process.env.NODE_ENV !== 'test') {
34
- await this.prompt.saveHistory()
35
- this.Logger.bold('Clear or close the terminal. If not, your history will be visible scrolling up.')
36
- this.Logger.reset('Bye bye :o)')
31
+ if (process.env.NODE_ENV !== "test") {
32
+ await this.prompt.saveHistory();
33
+ this.Logger.bold(
34
+ "Clear or close the terminal. If not, your history will be visible scrolling up."
35
+ );
36
+ this.Logger.reset("Bye bye :o)");
37
37
  /*eslint-disable-next-line*/
38
- process.exit(0)
38
+ process.exit(0);
39
39
  } else {
40
- this.Logger.reset('Bye bye :o)')
40
+ this.Logger.reset("Bye bye :o)");
41
41
  }
42
42
  }
43
43
  }
44
44
 
45
- module.exports = Quit
46
-
47
-
45
+ module.exports = Quit;
@@ -1,133 +1,141 @@
1
- const chalk = require('chalk')
2
- const fs = require('fs-extra')
3
- const path = require('path')
4
- const {Node} = require('@secrez/fs')
5
-
6
- class Rm extends require('../Command') {
1
+ const chalk = require("chalk");
2
+ const fs = require("fs-extra");
3
+ const path = require("path");
4
+ const { Node } = require("@secrez/fs");
7
5
 
6
+ class Rm extends require("../Command") {
8
7
  setHelpAndCompletion() {
9
8
  this.cliConfig.completion.rm = {
10
9
  _func: this.selfCompletion(this),
11
- _self: this
12
- }
13
- this.cliConfig.completion.help.rm = true
10
+ _self: this,
11
+ };
12
+ this.cliConfig.completion.help.rm = true;
14
13
  this.optionDefinitions = [
15
14
  {
16
- name: 'help',
17
- alias: 'h',
18
- type: Boolean
15
+ name: "help",
16
+ alias: "h",
17
+ type: Boolean,
19
18
  },
20
19
  {
21
- name: 'path',
22
- completionType: 'file',
23
- alias: 'p',
20
+ name: "path",
21
+ completionType: "file",
22
+ alias: "p",
24
23
  defaultOption: true,
25
- type: String
24
+ type: String,
26
25
  },
27
26
  {
28
- name: 'versions',
29
- alias: 'v',
27
+ name: "versions",
28
+ alias: "v",
30
29
  multiple: true,
31
- type: String
32
- }
33
- ]
30
+ type: String,
31
+ },
32
+ ];
34
33
  }
35
34
 
36
35
  help() {
37
36
  return {
38
- description: ['Removes one or more files and folders.',
37
+ description: [
38
+ "Removes one or more files and folders.",
39
39
  'Technically files are moved to the trash dataset (access it with "use trash").',
40
- 'If you remove a file from the trash dataset, the data will be deleted from disk;',
41
- 'this action is not undoable.'
40
+ "If you remove a file from the trash dataset, the data will be deleted from disk;",
41
+ "this action is not undoable.",
42
42
  ],
43
43
  examples: [
44
- 'rm secret1',
45
- ['rm secret2 -v au7t RF6z', 'deleted the versions "au7t" and "RF6z" of the file']
46
- ]
47
- }
44
+ "rm secret1",
45
+ [
46
+ "rm secret2 -v au7t RF6z",
47
+ 'deleted the versions "au7t" and "RF6z" of the file',
48
+ ],
49
+ ],
50
+ };
48
51
  }
49
52
 
50
53
  async rm(options = {}) {
51
- options.asIs = true
52
- options.newPath = 'trash:/'
53
- options.removing = true
54
+ options.asIs = true;
55
+ options.newPath = "trash:/";
56
+ options.removing = true;
54
57
 
55
- let nodes = await this.internalFs.fileList(options, null, true)
56
- let deleted = nodes.map(n => n.getPath())
58
+ let nodes = await this.internalFs.fileList(options, null, true);
59
+ let deleted = nodes.map((n) => n.getPath());
57
60
  if (deleted.length) {
58
-
59
61
  if (options.versions) {
60
62
  if (deleted.length > 1) {
61
- throw new Error('You can delete versions of a single file at time')
63
+ throw new Error("You can delete versions of a single file at time");
62
64
  }
63
65
  /* istanbul ignore if */
64
- if (!process.env.NODE_ENV === 'test') {
65
- this.Logger.reset('The deletion of a version is not reversible.')
66
- let message = 'Are you sure you want to proceed?'
66
+ if (!process.env.NODE_ENV === "test") {
67
+ this.Logger.reset("The deletion of a version is not reversible.");
68
+ let message = "Are you sure you want to proceed?";
67
69
  let yes = await this.useConfirm({
68
70
  message,
69
- default: false
70
- })
71
+ default: false,
72
+ });
71
73
  if (!yes) {
72
- return 'Operation canceled'
74
+ return "Operation canceled";
73
75
  }
74
76
  }
75
- let {datasetIndex} = Node.getRoot(nodes[0])
76
- let res = []
77
+ let { datasetIndex } = Node.getRoot(nodes[0]);
78
+ let res = [];
77
79
  for (let ts in nodes[0].versions) {
78
- let v = Node.hashVersion(ts)
80
+ let v = Node.hashVersion(ts);
79
81
  if (options.versions.indexOf(v) !== -1) {
80
- let file = nodes[0].versions[ts].file
81
- await fs.remove(path.join(this.secrez.config.dataPath + (datasetIndex ? `.${datasetIndex}` : ''), file))
82
- res.push(this.formatResult({
83
- name: path.basename(deleted[0]),
84
- version: v
85
- }))
86
- delete nodes[0].versions[ts]
87
- this.internalFs.trees[datasetIndex].save()
82
+ let file = nodes[0].versions[ts].file;
83
+ await fs.remove(
84
+ path.join(
85
+ this.secrez.config.dataPath +
86
+ (datasetIndex ? `.${datasetIndex}` : ""),
87
+ file
88
+ )
89
+ );
90
+ res.push(
91
+ this.formatResult({
92
+ name: path.basename(deleted[0]),
93
+ version: v,
94
+ })
95
+ );
96
+ delete nodes[0].versions[ts];
97
+ this.internalFs.trees[datasetIndex].save();
88
98
  }
89
99
  }
90
- return res
100
+ return res;
91
101
  }
92
- await this.prompt.commands.mv.mv(options, nodes)
102
+ await this.prompt.commands.mv.mv(options, nodes);
93
103
  }
94
- return deleted
104
+ return deleted;
95
105
  }
96
106
 
97
107
  formatResult(item) {
98
- return [chalk.yellow(item.version), item.name].join(' ')
108
+ return [chalk.yellow(item.version), item.name].join(" ");
99
109
  }
100
110
 
101
111
  async exec(options = {}) {
102
112
  if (options.help) {
103
- return this.showHelp()
113
+ return this.showHelp();
104
114
  }
105
115
  if (!options.path) {
106
- this.Logger.red('File path not specified.')
116
+ this.Logger.red("File path not specified.");
107
117
  } else {
108
118
  try {
109
- this.validate(options)
110
- let deleted = await this.rm(options)
119
+ this.validate(options);
120
+ let deleted = await this.rm(options);
111
121
  if (deleted.length === 0) {
112
- this.Logger.grey('No files have been deleted.')
122
+ this.Logger.grey("No files have been deleted.");
113
123
  } else {
114
- this.Logger.grey('Deleted entries:')
115
- if (typeof deleted === 'string') {
116
- this.Logger.reset(deleted)
124
+ this.Logger.grey("Deleted entries:");
125
+ if (typeof deleted === "string") {
126
+ this.Logger.reset(deleted);
117
127
  } else {
118
128
  for (let d of deleted) {
119
- this.Logger.reset(d)
129
+ this.Logger.reset(d);
120
130
  }
121
131
  }
122
132
  }
123
133
  } catch (e) {
124
- this.Logger.red(e.message)
134
+ this.Logger.red(e.message);
125
135
  }
126
136
  }
127
- await this.prompt.run()
137
+ await this.prompt.run();
128
138
  }
129
139
  }
130
140
 
131
- module.exports = Rm
132
-
133
-
141
+ module.exports = Rm;
@@ -1,62 +1,61 @@
1
- const {execSync} = require('child_process')
2
-
3
- class Shell extends require('../Command') {
1
+ const { execSync } = require("child_process");
4
2
 
3
+ class Shell extends require("../Command") {
5
4
  setHelpAndCompletion() {
6
5
  this.cliConfig.completion.shell = {
7
- _self: this
8
- }
9
- this.cliConfig.completion.help.shell = true
6
+ _self: this,
7
+ };
8
+ this.cliConfig.completion.help.shell = true;
10
9
  this.optionDefinitions = [
11
10
  {
12
- name: 'help',
13
- alias: 'h',
14
- type: Boolean
11
+ name: "help",
12
+ alias: "h",
13
+ type: Boolean,
15
14
  },
16
15
  {
17
- name: 'command',
18
- alias: 'c',
16
+ name: "command",
17
+ alias: "c",
19
18
  type: String,
20
- defaultOption: true
21
- }
22
- ]
19
+ defaultOption: true,
20
+ },
21
+ ];
23
22
  }
24
23
 
25
24
  help() {
26
25
  return {
27
- description: ['Execute a shell command in the current disk folder.'],
26
+ description: ["Execute a shell command in the current disk folder."],
28
27
  examples: [
29
28
  'shell "ls"',
30
- ['shell "mv wallet1 wallet2"', 'renames an external file'],
31
- ['shell', 'asks to type the command to execute']
32
- ]
33
- }
29
+ ['shell "mv wallet1 wallet2"', "renames an external file"],
30
+ ["shell", "asks to type the command to execute"],
31
+ ],
32
+ };
34
33
  }
35
34
 
36
35
  async shell(options) {
37
- let pwd = await this.prompt.commands.lpwd.lpwd()
36
+ let pwd = await this.prompt.commands.lpwd.lpwd();
38
37
  if (!options.command) {
39
- options.command = await this.useInput(Object.assign(options, {
40
- message: 'Type the command'
41
- }))
38
+ options.command = await this.useInput(
39
+ Object.assign(options, {
40
+ message: "Type the command",
41
+ })
42
+ );
42
43
  }
43
- return execSync(`cd ${pwd} && ${options.command}`).toString()
44
+ return execSync(`cd ${pwd} && ${options.command}`).toString();
44
45
  }
45
46
 
46
47
  async exec(options = {}) {
47
48
  if (options.help) {
48
- return this.showHelp()
49
+ return this.showHelp();
49
50
  }
50
51
  try {
51
- this.validate(options)
52
- this.Logger.reset(await this.shell(options))
52
+ this.validate(options);
53
+ this.Logger.reset(await this.shell(options));
53
54
  } catch (e) {
54
- this.Logger.red(e.message)
55
+ this.Logger.red(e.message);
55
56
  }
56
- await this.prompt.run()
57
+ await this.prompt.run();
57
58
  }
58
59
  }
59
60
 
60
- module.exports = Shell
61
-
62
-
61
+ module.exports = Shell;
@@ -1,110 +1,124 @@
1
- const path = require('path')
2
- const fs = require('fs-extra')
3
- const {execSync} = require('child_process')
4
- const {execAsync} = require('@secrez/utils')
5
-
6
- class Ssh extends require('../Command') {
1
+ const path = require("path");
2
+ const fs = require("fs-extra");
3
+ const { execSync } = require("child_process");
4
+ const { execAsync } = require("@secrez/utils");
7
5
 
6
+ class Ssh extends require("../Command") {
8
7
  setHelpAndCompletion() {
9
8
  this.cliConfig.completion.ssh = {
10
9
  _func: this.selfCompletion(this),
11
- _self: this
12
- }
13
- this.cliConfig.completion.help.ssh = true
10
+ _self: this,
11
+ };
12
+ this.cliConfig.completion.help.ssh = true;
14
13
  this.optionDefinitions = [
15
14
  {
16
- name: 'help',
17
- alias: 'h',
18
- type: Boolean
15
+ name: "help",
16
+ alias: "h",
17
+ type: Boolean,
19
18
  },
20
19
  {
21
- name: 'remote-host',
22
- alias: 'r',
20
+ name: "remote-host",
21
+ alias: "r",
23
22
  defaultOption: true,
24
- type: String
23
+ type: String,
25
24
  },
26
25
  {
27
- name: 'identity',
28
- completionType: 'file',
29
- alias: 'i',
30
- type: String
26
+ name: "identity",
27
+ completionType: "file",
28
+ alias: "i",
29
+ type: String,
31
30
  },
32
31
  {
33
- name: 'user',
34
- alias: 'u',
35
- type: String
32
+ name: "user",
33
+ alias: "u",
34
+ type: String,
36
35
  },
37
36
  {
38
- name: 'delete-after',
39
- alias: 'd',
40
- type: Number
37
+ name: "delete-after",
38
+ alias: "d",
39
+ type: Number,
41
40
  },
42
41
  {
43
- name: 'ignore-host-key-check',
44
- type: Boolean
45
- }
46
- ]
42
+ name: "ignore-host-key-check",
43
+ type: Boolean,
44
+ },
45
+ ];
47
46
  }
48
47
 
49
48
  help() {
50
49
  return {
51
50
  description: [
52
- 'Opens a new tab and run ssh to connect to a remote server via SSH',
53
- 'Notice that the SSH key is temporarily copied to ~/.ssh and removed after few seconds seconds.'
51
+ "Opens a new tab and run ssh to connect to a remote server via SSH",
52
+ "Notice that the SSH key is temporarily copied to ~/.ssh and removed after few seconds seconds.",
54
53
  ],
55
54
  examples: [
56
- ['ssh example.com -i id_ed25519 -u joe', 'connects using the private key "main:/.ssh/id_ed25519"'],
57
- ['ssh example.com -i keys:/id_rsa', 'connects as root using the private key "id_rsa" in the root of the "keys" dataset'],
58
- ['ssh example.com -i keys:/id_rsa_no -d 2', 'deletes the private key from the temporary folder after 2 seconds. The standard is 10 seconds to give you the time to type the password, but if the private key is passwordless you should reduce the time.']
59
- ]
60
- }
55
+ [
56
+ "ssh example.com -i id_ed25519 -u joe",
57
+ 'connects using the private key "main:/.ssh/id_ed25519"',
58
+ ],
59
+ [
60
+ "ssh example.com -i keys:/id_rsa",
61
+ 'connects as root using the private key "id_rsa" in the root of the "keys" dataset',
62
+ ],
63
+ [
64
+ "ssh example.com -i keys:/id_rsa_no -d 2",
65
+ "deletes the private key from the temporary folder after 2 seconds. The standard is 10 seconds to give you the time to type the password, but if the private key is passwordless you should reduce the time.",
66
+ ],
67
+ ],
68
+ };
61
69
  }
62
70
 
63
71
  async ssh(options = {}) {
64
- let result = await execAsync('which', __dirname, ['ttab'])
72
+ let result = await execAsync("which", __dirname, ["ttab"]);
65
73
  if (!result.message || result.code === 1) {
66
- throw new Error('On MacOS ttab is required. Run "npm i -g ttab" in another terminal to install it')
74
+ throw new Error(
75
+ 'On MacOS ttab is required. Run "npm i -g ttab" in another terminal to install it'
76
+ );
67
77
  }
68
78
  if (!options.remoteHost) {
69
- throw new Error('A remote host is required')
79
+ throw new Error("A remote host is required");
70
80
  }
71
81
  if (!options.identity) {
72
- throw new Error('A path to the identity key is required')
82
+ throw new Error("A path to the identity key is required");
73
83
  }
74
- let key = (await this.prompt.commands.cat.cat({
75
- path: options.identity,
76
- unformatted: true
77
- }))[0].content
78
- let sshPath = path.join(this.secrez.config.tmpPath, '.ssh')
84
+ let key = (
85
+ await this.prompt.commands.cat.cat({
86
+ path: options.identity,
87
+ unformatted: true,
88
+ })
89
+ )[0].content;
90
+ let sshPath = path.join(this.secrez.config.tmpPath, ".ssh");
79
91
  if (!(await fs.pathExists(sshPath))) {
80
- await fs.ensureDir(sshPath)
81
- await execAsync('chmod', this.secrez.config.tmpPath, ['700', '.ssh'])
92
+ await fs.ensureDir(sshPath);
93
+ await execAsync("chmod", this.secrez.config.tmpPath, ["700", ".ssh"]);
82
94
  }
83
- let keyName = `id_${Math.random().toString().substring(2)}`
84
- let keyPath = path.join(sshPath, keyName)
85
- await fs.writeFile(keyPath, key)
86
- await execAsync('chmod', sshPath, ['600', keyName])
87
- execSync(`ttab ssh ${options.ignoreHostKeyCheck ? '-oStrictHostKeyChecking=no' : ''} -i ${keyPath} ${options.user || 'root'}@${options.remoteHost}`)
95
+ let keyName = `id_${Math.random().toString().substring(2)}`;
96
+ let keyPath = path.join(sshPath, keyName);
97
+ await fs.writeFile(keyPath, key);
98
+ await execAsync("chmod", sshPath, ["600", keyName]);
99
+ execSync(
100
+ `ttab ssh ${
101
+ options.ignoreHostKeyCheck ? "-oStrictHostKeyChecking=no" : ""
102
+ } -i ${keyPath} ${options.user || "root"}@${options.remoteHost}`
103
+ );
88
104
  setTimeout(() => {
89
- fs.unlink(keyPath)
90
- }, 10000)
105
+ fs.unlink(keyPath);
106
+ }, 10000);
91
107
  }
92
108
 
93
109
  async exec(options = {}) {
94
110
  if (options.help) {
95
- return this.showHelp()
111
+ return this.showHelp();
96
112
  }
97
113
  try {
98
- this.validate(options)
99
- let result = await this.ssh(options)
100
- this.Logger.reset(result)
114
+ this.validate(options);
115
+ let result = await this.ssh(options);
116
+ this.Logger.reset(result);
101
117
  } catch (e) {
102
- this.Logger.red(e.message)
118
+ this.Logger.red(e.message);
103
119
  }
104
- await this.prompt.run()
120
+ await this.prompt.run();
105
121
  }
106
122
  }
107
123
 
108
- module.exports = Ssh
109
-
110
-
124
+ module.exports = Ssh;