secrez 1.1.1 → 1.1.3

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 +503 -444
  2. package/bin/secrez.js +50 -47
  3. package/coverage.report +91 -85
  4. package/package.json +10 -12
  5. package/src/Command.js +78 -57
  6. package/src/PreCommand.js +75 -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 +201 -116
  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,98 +1,211 @@
1
- const {config, Entry} = require('@secrez/core')
2
-
3
- class Touch extends require('../Command') {
1
+ const { config, Entry } = require("@secrez/core");
2
+ const { yamlStringify } = require("@secrez/utils");
3
+ const { newWallet, getWalletFromMnemonic } = require("@secrez/eth");
4
4
 
5
+ class Touch extends require("../Command") {
5
6
  setHelpAndCompletion() {
6
7
  this.cliConfig.completion.touch = {
7
8
  _func: this.selfCompletion(this),
8
- _self: this
9
- }
10
- this.cliConfig.completion.help.touch = true
9
+ _self: this,
10
+ };
11
+ this.cliConfig.completion.help.touch = true;
11
12
  this.optionDefinitions = [
12
13
  {
13
- name: 'help',
14
- alias: 'h',
15
- type: Boolean
14
+ name: "help",
15
+ alias: "h",
16
+ type: Boolean,
16
17
  },
17
18
  {
18
- name: 'path',
19
- completionType: 'file',
20
- alias: 'p',
19
+ name: "path",
20
+ completionType: "file",
21
+ alias: "p",
21
22
  defaultOption: true,
22
- type: String
23
+ type: String,
23
24
  },
24
25
  {
25
- name: 'content',
26
- alias: 'c',
27
- type: String
26
+ name: "content",
27
+ alias: "c",
28
+ type: String,
28
29
  },
29
30
  {
30
- name: 'not-visible-content',
31
- alias: 'n',
32
- type: Boolean
31
+ name: "prefix",
32
+ alias: "x",
33
+ type: String,
33
34
  },
34
35
  {
35
- name: 'version-if-exists',
36
- alias: 'v',
37
- type: Boolean
38
- }
39
- ]
36
+ name: "wait-for-content",
37
+ alias: "w",
38
+ type: Boolean,
39
+ },
40
+ {
41
+ name: "not-visible-content",
42
+ alias: "n",
43
+ type: Boolean,
44
+ },
45
+ {
46
+ name: "generate-wallet",
47
+ alias: "g",
48
+ type: Boolean,
49
+ },
50
+ {
51
+ name: "amount",
52
+ alias: "a",
53
+ type: Number,
54
+ },
55
+ {
56
+ name: "include-mnemonic",
57
+ alias: "m",
58
+ type: Boolean,
59
+ },
60
+ {
61
+ name: "version-if-exists",
62
+ alias: "v",
63
+ type: Boolean,
64
+ },
65
+ ];
40
66
  }
41
67
 
42
68
  help() {
43
69
  return {
44
- description: ['Creates a file.',
70
+ description: [
71
+ "Creates a file.",
45
72
  'Compared with Unix "touch" command, it can create a file with content',
46
- 'Check also "help create" for more options.'
73
+ 'Check also "help create" for more options.',
47
74
  ],
48
75
  examples: [
49
- 'touch somefile',
76
+ [
77
+ "touch somefile",
78
+ "If the the file exists, it create 'somefile.2', 'somefile.3', etc.",
79
+ ],
50
80
  'touch -p afile --content "Password: 1432874565"',
51
81
  'touch ether -c "Private Key: eweiu34y23h4y23ih4uy23hiu4y234i23y4iuh3"',
52
- ['touch ether -v', 'Save the file as ether.2 if ether already exists']
53
- ]
54
- }
82
+ [
83
+ "touch sample.txt -e",
84
+ "Prompt the user to type the content of the file. The text cannot contain newlines. It will cut at the first one, if so. If '-e' and '-c' are both present, '-c' will be ignored.",
85
+ ],
86
+ [
87
+ "touch walletPassword -n",
88
+ "Prompt the user to type the password without showing it. Notice that '-n' has priority on '-e' and '-c'",
89
+ ],
90
+ [
91
+ "touch gilbert -f name -c 'Albert Goose'",
92
+ "If the file does not exists, it creates 'gilbert.yaml' with the field 'name'. If a yaml file exists, it adds the field 'name' to it if the the field does not exist.",
93
+ ],
94
+ [
95
+ "touch new-wallet -w",
96
+ "Creates a new wallet file containing 'private_key' and `address`. Wallet has priority on other creation options.",
97
+ ],
98
+ [
99
+ "touch new-wallets.yaml -w -n 3",
100
+ "Creates 'new-wallets.yaml', containing 3 wallet, calling them 'private_key', `private_key2` and `private_key3`, and relative addresses.",
101
+ ],
102
+ [
103
+ "touch new-wallet --wallet -x trust0",
104
+ "In combination con '-x', it creates a new wallet file calling the fields 'trust0_private_key' and 'trust0_address'.",
105
+ ],
106
+ [
107
+ "touch new-wallets.yaml -wi",
108
+ "Includes the mnemonic. In this case, it will also add the fields 'mnemonic' (mnemonic phrase) and 'derived_path' (path used to generate the keys). ",
109
+ ],
110
+ ],
111
+ };
55
112
  }
56
113
 
57
114
  async touch(options = {}) {
58
- this.checkPath(options)
59
- let data = await this.internalFs.getTreeIndexAndPath(options.path)
60
- let sanitizedPath = Entry.sanitizePath(data.path)
61
- if (sanitizedPath !== data.path) {
62
- throw new Error('A filename cannot contain \\/><|:&?*^$ chars.')
115
+ this.checkPath(options);
116
+ let data = await this.internalFs.getTreeIndexAndPath(options.path);
117
+ let fileExists = false;
118
+ let node;
119
+ if (options.generateWallet) {
120
+ let content = {};
121
+ let amount = options.amount || 1;
122
+ let wallet = newWallet();
123
+ for (let i = 1; i <= amount; i++) {
124
+ let wallet0;
125
+ if (i === 1) {
126
+ wallet0 = wallet;
127
+ } else {
128
+ wallet0 = getWalletFromMnemonic(
129
+ wallet.mnemonic.phrase,
130
+ wallet.path,
131
+ i - 1
132
+ );
133
+ }
134
+ let field = `${options.prefix ? options.prefix + "_" : ""}private_key${
135
+ i > 1 ? i : ""
136
+ }`;
137
+ content[field] = wallet0.privateKey.replace(/^0x/, "");
138
+ content[field.replace(/private_key/, "address")] = wallet0.address;
139
+ if (i === 1 && options.includeMnemonic) {
140
+ content[field.replace(/private_key/, "mnemonic")] =
141
+ wallet.mnemonic.phrase;
142
+ let derivedPath = wallet.path;
143
+ if (derivedPath.split("/").length === 6) {
144
+ derivedPath = derivedPath.replace(/\/0$/, "");
145
+ }
146
+ content[field.replace(/private_key/, "derived_path")] = derivedPath;
147
+ }
148
+ }
149
+ options.content = yamlStringify(content);
150
+ }
151
+ if (fileExists) {
152
+ await this.internalFs.tree.update(node, options.content);
153
+ } else {
154
+ let sanitizedPath = Entry.sanitizePath(data.path);
155
+ if (sanitizedPath !== data.path) {
156
+ throw new Error("A filename cannot contain \\/><|:&?*^$ chars.");
157
+ }
158
+ options.type = config.types.TEXT;
159
+ return await this.internalFs.make(options);
63
160
  }
64
- options.type = config.types.TEXT
65
- return await this.internalFs.make(options)
66
161
  }
67
162
 
68
163
  async exec(options = {}) {
69
164
  if (options.help) {
70
- return this.showHelp()
165
+ return this.showHelp();
71
166
  }
72
167
  try {
73
- this.validate(options)
74
- this.checkPath(options)
168
+ this.validate(options);
169
+ this.checkPath(options);
75
170
  /* istanbul ignore if */
76
- if (options.notVisibleContent) {
77
- let content = await this.useInput(Object.assign(options, {
78
- type: 'password',
79
- message: 'Type the secret'
80
- }))
81
- if (content) {
82
- options.content = content
83
- } else {
84
- throw new Error('Command canceled')
171
+ if (!options.generateWallet) {
172
+ if (options.notVisibleContent) {
173
+ let content = await this.useInput(
174
+ Object.assign(options, {
175
+ type: "password",
176
+ message: "Type the secret",
177
+ })
178
+ );
179
+ if (content) {
180
+ options.content = content;
181
+ } else {
182
+ throw new Error("Command canceled");
183
+ }
184
+ } else if (options.waitForContent) {
185
+ let content = await this.useInput(
186
+ Object.assign(options, {
187
+ type: "input",
188
+ message: "Type/paste the content",
189
+ })
190
+ );
191
+ if (content) {
192
+ options.content = content;
193
+ } else {
194
+ throw new Error("Command canceled");
195
+ }
85
196
  }
86
197
  }
87
- let newFile = await this.touch(options)
88
- this.Logger.grey(`New file "${newFile.getPath()}" created.`)
198
+ let newFile = await this.touch(options);
199
+ if (newFile) {
200
+ this.Logger.grey(`New file "${newFile.getPath()}" created.`);
201
+ } else {
202
+ this.Logger.grey(`File "${options.path}" updated.`);
203
+ }
89
204
  } catch (e) {
90
- this.Logger.red(e.message)
205
+ this.Logger.red(e.message);
91
206
  }
92
- await this.prompt.run()
207
+ await this.prompt.run();
93
208
  }
94
209
  }
95
210
 
96
- module.exports = Touch
97
-
98
-
211
+ module.exports = Touch;
@@ -1,86 +1,89 @@
1
- class Use extends require('../Command') {
2
-
1
+ class Use extends require("../Command") {
3
2
  setHelpAndCompletion() {
4
3
  this.cliConfig.completion.use = {
5
4
  _func: this.selfCompletion(this),
6
- _self: this
7
- }
8
- this.cliConfig.completion.help.use = true
5
+ _self: this,
6
+ };
7
+ this.cliConfig.completion.help.use = true;
9
8
  this.optionDefinitions = [
10
9
  {
11
- name: 'help',
12
- alias: 'h',
13
- type: Boolean
10
+ name: "help",
11
+ alias: "h",
12
+ type: Boolean,
14
13
  },
15
14
  {
16
- name: 'dataset',
17
- completionType: 'dataset',
18
- alias: 'd',
15
+ name: "dataset",
16
+ completionType: "dataset",
17
+ alias: "d",
19
18
  defaultOption: true,
20
- type: String
19
+ type: String,
21
20
  },
22
21
  {
23
- name: 'create',
24
- alias: 'c',
25
- type: Boolean
26
- }
27
- ]
22
+ name: "create",
23
+ alias: "c",
24
+ type: Boolean,
25
+ },
26
+ ];
28
27
  }
29
28
 
30
29
  help() {
31
30
  return {
32
- description: ['Uses a specific dataset.'],
31
+ description: ["Uses a specific dataset."],
33
32
  examples: [
34
- ['use archive', 'use "archive" dataset if it exists'],
35
- ['use -c archive', 'use the dataset named "archive";', 'if the dataset does not exists it creates it']
36
- ]
37
- }
33
+ ["use archive", 'use "archive" dataset if it exists'],
34
+ [
35
+ "use -c archive",
36
+ 'use the dataset named "archive";',
37
+ "if the dataset does not exists it creates it",
38
+ ],
39
+ ],
40
+ };
38
41
  }
39
42
 
40
43
  async use(options) {
41
- let datasetsInfo = await this.internalFs.getDatasetsInfo()
44
+ let datasetsInfo = await this.internalFs.getDatasetsInfo();
42
45
  if (options.dataset) {
43
- let newSet
46
+ let newSet;
44
47
  for (let dataset of datasetsInfo) {
45
48
  if (dataset.name.toLowerCase() === options.dataset.toLowerCase()) {
46
- newSet = dataset
47
- break
49
+ newSet = dataset;
50
+ break;
48
51
  }
49
52
  }
50
53
  if (!newSet && !options.create) {
51
- throw new Error('The dataset does not exist; add "-c" to create it')
54
+ throw new Error('The dataset does not exist; add "-c" to create it');
52
55
  }
53
56
  if (newSet && newSet.index === this.internalFs.treeIndex) {
54
- return `You are already using ${options.dataset}`
57
+ return `You are already using ${options.dataset}`;
55
58
  } else if (newSet) {
56
- await this.internalFs.mountTree(newSet.index, true)
59
+ await this.internalFs.mountTree(newSet.index, true);
57
60
  } else {
58
61
  // create
59
- this.internalFs.tree.validateDatasetName(options.dataset)
60
- let index = datasetsInfo[datasetsInfo.length - 1].index + 1
61
- await this.internalFs.mountTree(index, true)
62
- await this.internalFs.tree.nameDataset(options.dataset)
62
+ this.internalFs.tree.validateDatasetName(options.dataset);
63
+ let index = datasetsInfo[datasetsInfo.length - 1].index + 1;
64
+ await this.internalFs.mountTree(index, true);
65
+ await this.internalFs.tree.nameDataset(options.dataset);
63
66
  }
64
67
  } else {
65
- throw new Error('Wrong parameters')
68
+ throw new Error("Wrong parameters");
66
69
  }
67
70
  }
68
71
 
69
72
  async exec(options = {}) {
70
73
  if (options.help) {
71
- return this.showHelp()
74
+ return this.showHelp();
72
75
  }
73
76
  try {
74
- this.validate(options)
75
- let result = await this.use(options)
77
+ this.validate(options);
78
+ let result = await this.use(options);
76
79
  if (result) {
77
- this.Logger.reset(result)
80
+ this.Logger.reset(result);
78
81
  }
79
82
  } catch (e) {
80
- this.Logger.red(e.message)
83
+ this.Logger.red(e.message);
81
84
  }
82
- await this.prompt.run()
85
+ await this.prompt.run();
83
86
  }
84
87
  }
85
88
 
86
- module.exports = Use
89
+ module.exports = Use;
@@ -1,34 +1,32 @@
1
- const pkg = require('../../package')
2
-
3
- class Ver extends require('../Command') {
1
+ const pkg = require("../../package");
4
2
 
3
+ class Ver extends require("../Command") {
5
4
  setHelpAndCompletion() {
6
- this.cliConfig.completion.ver = {}
7
- this.cliConfig.completion.help.ver = true
5
+ this.cliConfig.completion.ver = {};
6
+ this.cliConfig.completion.help.ver = true;
8
7
  this.optionDefinitions = [
9
8
  {
10
- name: 'help',
11
- alias: 'h',
12
- type: Boolean
13
- }]
9
+ name: "help",
10
+ alias: "h",
11
+ type: Boolean,
12
+ },
13
+ ];
14
14
  }
15
15
 
16
16
  help() {
17
17
  return {
18
- description: ['Shows the version of Secrez.'],
19
- examples: [
20
- 'ver'
21
- ]
22
- }
18
+ description: ["Shows the version of Secrez."],
19
+ examples: ["ver"],
20
+ };
23
21
  }
24
22
 
25
23
  async exec(options = {}) {
26
24
  if (options.help) {
27
- return this.showHelp()
25
+ return this.showHelp();
28
26
  }
29
- this.Logger.reset(`v${pkg.version}`)
30
- await this.prompt.run()
27
+ this.Logger.reset(`v${pkg.version}`);
28
+ await this.prompt.run();
31
29
  }
32
30
  }
33
31
 
34
- module.exports = Ver
32
+ module.exports = Ver;
@@ -1,73 +1,70 @@
1
- const chalk = require('chalk')
2
- const {ConfigUtils} = require('@secrez/core')
3
- const clipboardy = require('clipboardy')
4
-
5
- class Whoami extends require('../Command') {
1
+ const chalk = require("chalk");
2
+ const { ConfigUtils } = require("@secrez/core");
3
+ const clipboardy = require("clipboardy");
6
4
 
5
+ class Whoami extends require("../Command") {
7
6
  setHelpAndCompletion() {
8
7
  this.cliConfig.completion.whoami = {
9
8
  _func: this.selfCompletion(this),
10
- _self: this
11
- }
12
- this.cliConfig.completion.help.whoami = true
9
+ _self: this,
10
+ };
11
+ this.cliConfig.completion.help.whoami = true;
13
12
  this.optionDefinitions = [
14
13
  {
15
- name: 'help',
16
- alias: 'h',
17
- type: Boolean
18
- }
19
- ]
14
+ name: "help",
15
+ alias: "h",
16
+ type: Boolean,
17
+ },
18
+ ];
20
19
  }
21
20
 
22
21
  help() {
23
22
  return {
24
- description: ['Show data that other users need to chat with you'],
25
- examples: [
26
- 'whoami'
27
- ]
28
- }
23
+ description: ["Show data that other users need to chat with you"],
24
+ examples: ["whoami"],
25
+ };
29
26
  }
30
27
 
31
28
  async customCompletion(options, originalLine, defaultOption) {
32
- return []
29
+ return [];
33
30
  }
34
31
 
35
32
  async whoami(options) {
36
33
  let result = {
37
- publicKey: this.secrez.getPublicKey()
38
- }
39
- const env = options.env = await ConfigUtils.getEnv(this.secrez.config)
34
+ publicKey: this.secrez.getPublicKey(),
35
+ };
36
+ const env = (options.env = await ConfigUtils.getEnv(this.secrez.config));
40
37
  if (env.courier) {
41
- await this.prompt.commands.courier.preInit(options)
38
+ await this.prompt.commands.courier.preInit(options);
42
39
  if (options.ready) {
43
- result.url = env.courier.tunnel.url
40
+ result.url = env.courier.tunnel.url;
44
41
  }
45
42
  }
46
43
  if (options.asIs) {
47
- return result
44
+ return result;
48
45
  }
49
- this.Logger.reset(chalk.grey('Public key: ') + result.publicKey)
46
+ this.Logger.reset(chalk.grey("Public key: ") + result.publicKey);
50
47
  if (result.url) {
51
- this.Logger.reset(chalk.grey('Hub url: ') + result.url)
52
- await clipboardy.write(result.url)
53
- this.Logger.grey('For your convenience, the url has been copied to the clipboard.')
48
+ this.Logger.reset(chalk.grey("Hub url: ") + result.url);
49
+ await clipboardy.write(result.url);
50
+ this.Logger.grey(
51
+ "For your convenience, the url has been copied to the clipboard."
52
+ );
54
53
  }
55
54
  }
56
55
 
57
56
  async exec(options = {}) {
58
57
  if (options.help) {
59
- return this.showHelp()
58
+ return this.showHelp();
60
59
  }
61
60
  try {
62
- this.validate(options)
63
- await this.whoami(options)
61
+ this.validate(options);
62
+ await this.whoami(options);
64
63
  } catch (e) {
65
- this.Logger.red(e.message)
64
+ this.Logger.red(e.message);
66
65
  }
67
- await this.prompt.run()
66
+ await this.prompt.run();
68
67
  }
69
68
  }
70
69
 
71
- module.exports = Whoami
72
-
73
-
70
+ module.exports = Whoami;