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,105 +1,127 @@
1
- const {authenticator} = require('otplib')
2
- const path = require('path')
3
- const fs = require('fs-extra')
4
- const {execSync} = require('child_process')
5
- const {isYaml, yamlParse, yamlStringify, execAsync, TRUE} = require('@secrez/utils')
6
- const {Node} = require('@secrez/fs')
7
- const QrCode = require('qrcode-reader')
8
- const Jimp = require('jimp')
9
-
10
- class Totp extends require('../Command') {
1
+ const { authenticator } = require("otplib");
2
+ const path = require("path");
3
+ const fs = require("fs-extra");
4
+ const { execSync } = require("child_process");
5
+ const {
6
+ isYaml,
7
+ yamlParse,
8
+ yamlStringify,
9
+ execAsync,
10
+ TRUE,
11
+ } = require("@secrez/utils");
12
+ const { Node } = require("@secrez/fs");
13
+ const QrCode = require("qrcode-reader");
14
+ const Jimp = require("jimp");
11
15
 
16
+ class Totp extends require("../Command") {
12
17
  setHelpAndCompletion() {
13
18
  this.cliConfig.completion.totp = {
14
19
  _func: this.selfCompletion(this),
15
- _self: this
16
- }
17
- this.cliConfig.completion.help.totp = true
20
+ _self: this,
21
+ };
22
+ this.cliConfig.completion.help.totp = true;
18
23
  this.optionDefinitions = [
19
24
  {
20
- name: 'help',
21
- alias: 'h',
22
- type: Boolean
25
+ name: "help",
26
+ alias: "h",
27
+ type: Boolean,
23
28
  },
24
29
  {
25
- name: 'path',
26
- completionType: 'file',
27
- alias: 'p',
30
+ name: "path",
31
+ completionType: "file",
32
+ alias: "p",
28
33
  defaultOption: true,
29
- type: String
34
+ type: String,
30
35
  },
31
36
  {
32
- name: 'duration',
33
- alias: 'd',
34
- type: Number
37
+ name: "duration",
38
+ alias: "d",
39
+ type: Number,
35
40
  },
36
41
  {
37
- name: 'no-beep',
38
- type: Boolean
42
+ name: "no-beep",
43
+ type: Boolean,
39
44
  },
40
45
  {
41
- name: 'from-clipboard',
42
- alias: 'c',
43
- type: Boolean
46
+ name: "from-clipboard",
47
+ alias: "c",
48
+ type: Boolean,
44
49
  },
45
50
  {
46
- name: 'from-image',
47
- alias: 'i',
48
- type: String
51
+ name: "from-image",
52
+ alias: "i",
53
+ type: String,
49
54
  },
50
55
  {
51
- name: 'set',
52
- alias: 's',
53
- type: String
56
+ name: "set",
57
+ alias: "s",
58
+ type: String,
54
59
  },
55
60
  {
56
- name: 'force',
57
- type: Boolean
61
+ name: "force",
62
+ type: Boolean,
58
63
  },
59
64
  {
60
- name: 'test',
61
- type: String
62
- }
63
- ]
65
+ name: "test",
66
+ type: String,
67
+ },
68
+ ];
64
69
  this.defaults = {
65
- duration: 8
66
- }
70
+ duration: 8,
71
+ };
67
72
  }
68
73
 
69
74
  help() {
70
75
  return {
71
- description: [
72
- 'Generate a TOTP code if a totp field exists in the card.'
73
- ],
76
+ description: ["Generate a TOTP code if a totp field exists in the card."],
74
77
  examples: [
75
- ['totp coinbase.yml', 'prints a totp code and copies it to the clipboard for 5 seconds'],
76
- ['totp coinbase.yml -s "9syh 34rd ge6s hey3 u874"', 'set up a totp code, if not set yet'],
77
- ['totp github.com.yml -s USyehAA35TSE --force', 'update an existing totp code'],
78
- ['totp coinbase.yml -d 2', 'keeps it in the clipboard for 2 seconds'],
79
- ['totp github.yml --from-clipboard', 'get a secret from a qr code copied in the clipboard and add a field "totp" with the secret in "github.yml"'],
80
- ['totp github.yml --from-image qrcode.png', 'get a secret from the image'],
81
- ['totp --test "IHSG UY6T WTGS"', 'tests a secret']
82
- ]
83
- }
78
+ [
79
+ "totp coinbase.yml",
80
+ "prints a totp code and copies it to the clipboard for 5 seconds",
81
+ ],
82
+ [
83
+ 'totp coinbase.yml -s "9syh 34rd ge6s hey3 u874"',
84
+ "set up a totp code, if not set yet",
85
+ ],
86
+ [
87
+ "totp github.com.yml -s USyehAA35TSE --force",
88
+ "update an existing totp code",
89
+ ],
90
+ ["totp coinbase.yml -d 2", "keeps it in the clipboard for 2 seconds"],
91
+ [
92
+ "totp github.yml --from-clipboard",
93
+ 'get a secret from a qr code copied in the clipboard and add a field "totp" with the secret in "github.yml"',
94
+ ],
95
+ [
96
+ "totp github.yml --from-image qrcode.png",
97
+ "get a secret from the image",
98
+ ],
99
+ ['totp --test "IHSG UY6T WTGS"', "tests a secret"],
100
+ ],
101
+ };
84
102
  }
85
103
 
86
104
  async isImagePasteSupported() {
87
105
  /* istanbul ignore if */
88
106
  if (TRUE()) {
89
- let result
107
+ let result;
90
108
  switch (process.platform) {
91
- case 'darwin':
92
- result = await execAsync('which', __dirname, ['pngpaste'])
109
+ case "darwin":
110
+ result = await execAsync("which", __dirname, ["pngpaste"]);
93
111
  if (!result.message || result.code === 1) {
94
- throw new Error('pngpaste is required. Run "brew install pngpaste" in another terminal to install it')
112
+ throw new Error(
113
+ 'pngpaste is required. Run "brew install pngpaste" in another terminal to install it'
114
+ );
95
115
  }
96
- break
97
- case 'win32':
98
- throw new Error('Operation not supported on Windows')
116
+ break;
117
+ case "win32":
118
+ throw new Error("Operation not supported on Windows");
99
119
  default:
100
- result = await execAsync('which', __dirname, ['xclip'])
120
+ result = await execAsync("which", __dirname, ["xclip"]);
101
121
  if (!result.message || result.code === 1) {
102
- throw new Error('xclip is required. On Debian/Ubuntu you can install it with "sudo apt install xclip"')
122
+ throw new Error(
123
+ 'xclip is required. On Debian/Ubuntu you can install it with "sudo apt install xclip"'
124
+ );
103
125
  }
104
126
  }
105
127
  }
@@ -108,155 +130,163 @@ class Totp extends require('../Command') {
108
130
  async readFromClipboard(options) {
109
131
  /* istanbul ignore if */
110
132
  if (TRUE()) {
111
- await this.isImagePasteSupported()
112
- let p = path.resolve(this.secrez.config.tmpPath, 'image.png')
113
- let result
133
+ await this.isImagePasteSupported();
134
+ let p = path.resolve(this.secrez.config.tmpPath, "image.png");
135
+ let result;
114
136
  switch (process.platform) {
115
- case 'darwin':
116
- result = await execAsync('pngpaste', __dirname, [p])
137
+ case "darwin":
138
+ result = await execAsync("pngpaste", __dirname, [p]);
117
139
  if (result.error) {
118
140
  if (/target image\/png not available/.test(result.error)) {
119
- throw new Error('The clipboard does not contain an image')
141
+ throw new Error("The clipboard does not contain an image");
120
142
  }
121
- throw new Error(result.error)
143
+ throw new Error(result.error);
122
144
  }
123
- break
145
+ break;
124
146
  default:
125
147
  try {
126
- result = execSync(`xclip -selection clipboard -t image/png -o > ${p}`).toString()
148
+ result = execSync(
149
+ `xclip -selection clipboard -t image/png -o > ${p}`
150
+ ).toString();
127
151
  } catch (e) {
128
- throw new Error('Wrong content in the clipboard')
152
+ throw new Error("Wrong content in the clipboard");
129
153
  }
130
154
  }
131
- return p
155
+ return p;
132
156
  }
133
157
  }
134
158
 
135
159
  async readFromImage(options) {
136
- let p = this.externalFs.getNormalizedPath(options.fromImage)
137
- const buffer = await fs.readFile(p)
160
+ let p = this.externalFs.getNormalizedPath(options.fromImage);
161
+ const buffer = await fs.readFile(p);
138
162
  return new Promise((resolve, reject) => {
139
163
  Jimp.read(buffer, (err, image) => {
140
164
  if (err) {
141
- reject(err.message)
165
+ reject(err.message);
142
166
  }
143
- const qr = new QrCode()
167
+ const qr = new QrCode();
144
168
  qr.callback = (err, value) => {
145
169
  /* istanbul ignore if */
146
170
  if (err) {
147
- reject(err.message)
171
+ reject(err.message);
148
172
  }
149
- resolve(value.result)
150
- }
173
+ resolve(value.result);
174
+ };
151
175
  try {
152
- qr.decode(image.bitmap)
176
+ qr.decode(image.bitmap);
153
177
  } catch (e) {
154
- reject(e.message)
178
+ reject(e.message);
155
179
  }
156
- })
157
- })
180
+ });
181
+ });
158
182
  }
159
183
 
160
184
  async totp(options = {}) {
161
- let secret = options.set
162
- let originalPath = options.path
185
+ let secret = options.set;
186
+ let originalPath = options.path;
163
187
  if (options.test) {
164
- const token = authenticator.generate(options.test.replace(/\s/g, ''))
165
- return token
188
+ const token = authenticator.generate(options.test.replace(/\s/g, ""));
189
+ return token;
166
190
  }
167
191
  if (options.fromImage || options.fromClipboard) {
168
192
  /* istanbul ignore if */
169
193
  if (options.fromClipboard) {
170
- options.fromImage = await this.readFromClipboard(options)
194
+ options.fromImage = await this.readFromClipboard(options);
171
195
  }
172
196
  try {
173
- let result = await this.readFromImage(options)
174
- secret = result.split('secret=')[1].split('&')[0]
197
+ let result = await this.readFromImage(options);
198
+ secret = result.split("secret=")[1].split("&")[0];
175
199
  } catch (e) {
176
- throw new Error('The file does not look like a valid 2FA QR code')
200
+ throw new Error("The file does not look like a valid 2FA QR code");
177
201
  }
178
202
  }
179
- let err = 'The file is not a card with a totp field'
180
- let currentIndex = this.internalFs.treeIndex
181
- let data = await this.internalFs.getTreeIndexAndPath(options.path)
203
+ let err = "The file is not a card with a totp field";
204
+ let currentIndex = this.internalFs.treeIndex;
205
+ let data = await this.internalFs.getTreeIndexAndPath(options.path);
182
206
  /* istanbul ignore if */
183
207
  if (currentIndex !== data.index) {
184
- await this.internalFs.mountTree(data.index, true)
208
+ await this.internalFs.mountTree(data.index, true);
185
209
  }
186
210
  if (secret && !originalPath) {
187
- return `The secret in the QR Code is "${secret}"`
211
+ return `The secret in the QR Code is "${secret}"`;
188
212
  }
189
- options.path = data.path
190
- let tree = data.tree
191
- let p = tree.getNormalizedPath(options.path)
192
- let node = tree.root.getChildFromPath(p)
213
+ options.path = data.path;
214
+ let tree = data.tree;
215
+ let p = tree.getNormalizedPath(options.path);
216
+ let node = tree.root.getChildFromPath(p);
193
217
  if (Node.isFile(node)) {
194
- let entry = (await this.prompt.commands.cat.cat({
195
- path: p,
196
- unformatted: true
197
- }))[0]
218
+ let entry = (
219
+ await this.prompt.commands.cat.cat({
220
+ path: p,
221
+ unformatted: true,
222
+ })
223
+ )[0];
198
224
  if (Node.isText(entry)) {
199
- let {content} = entry
225
+ let { content } = entry;
200
226
  if (isYaml(p) && !options.allFile) {
201
- let parsed
227
+ let parsed;
202
228
  try {
203
- parsed = yamlParse(content)
229
+ parsed = yamlParse(content);
204
230
  } catch (e) {
205
- throw new Error('The yml is malformed')
231
+ throw new Error("The yml is malformed");
206
232
  }
207
233
  if (secret) {
208
234
  if (parsed.totp && !options.force) {
209
- throw new Error('A totp already set. Use the "--force" option to override it')
235
+ throw new Error(
236
+ 'A totp already set. Use the "--force" option to override it'
237
+ );
210
238
  }
211
- parsed.totp = secret
212
- let entry = node.getEntry()
213
- entry.set('content', yamlStringify(parsed))
214
- await this.internalFs.tree.update(node, entry)
239
+ parsed.totp = secret;
240
+ let entry = node.getEntry();
241
+ entry.set("content", yamlStringify(parsed));
242
+ await this.internalFs.tree.update(node, entry);
215
243
  return [
216
- 'A totp field has been successfully created.',
217
- `Try it, running "totp ${node.getPath()}"`
218
- ].join('\n')
244
+ "A totp field has been successfully created.",
245
+ `Try it, running "totp ${node.getPath()}"`,
246
+ ].join("\n");
219
247
  } else {
220
- let totp = parsed.totp
248
+ let totp = parsed.totp;
221
249
  if (totp) {
222
- totp = totp.replace(/\s/g, '')
223
- const token = authenticator.generate(totp)
250
+ totp = totp.replace(/\s/g, "");
251
+ const token = authenticator.generate(totp);
224
252
  this.prompt.commands.copy.copy({
225
253
  thisString: token,
226
254
  duration: [options.duration || this.defaults.duration],
227
- noBeep: options.noBeep
228
- })
229
- return token
255
+ noBeep: options.noBeep,
256
+ });
257
+ return token;
230
258
  }
231
259
  }
232
260
  }
233
261
  }
234
262
  }
235
- throw new Error(err)
263
+ throw new Error(err);
236
264
  }
237
265
 
238
266
  async exec(options = {}) {
239
267
  if (options.help) {
240
- return this.showHelp()
268
+ return this.showHelp();
241
269
  }
242
270
  try {
243
- this.validate(options)
244
- let token = await this.totp(options)
271
+ this.validate(options);
272
+ let token = await this.totp(options);
245
273
  if (options.fromImage || options.fromClipboard) {
246
- this.Logger.grey(token)
274
+ this.Logger.grey(token);
247
275
  } else {
248
- this.Logger.grey('TOTP token: ' + this.chalk.bold.black(token))
276
+ this.Logger.grey("TOTP token: " + this.chalk.bold.black(token));
249
277
  if (!options.test) {
250
- this.Logger.grey(`It will stay in the clipboard for ${options.duration || this.defaults.duration} seconds`)
278
+ this.Logger.grey(
279
+ `It will stay in the clipboard for ${
280
+ options.duration || this.defaults.duration
281
+ } seconds`
282
+ );
251
283
  }
252
284
  }
253
285
  } catch (e) {
254
- this.Logger.red(e.message)
286
+ this.Logger.red(e.message);
255
287
  }
256
- await this.prompt.run()
288
+ await this.prompt.run();
257
289
  }
258
290
  }
259
291
 
260
- module.exports = Totp
261
-
262
-
292
+ module.exports = Totp;