mpw 4.1.1 → 4.2.0

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.
data/i18n/fr.yml CHANGED
@@ -111,8 +111,10 @@ fr:
111
111
  login: "L'identifiant a été copié dans le presse papier"
112
112
  password: "Le mot de passe a été copié dans le presse papier pour 30s!"
113
113
  otp: "Le code OTP a été copié dans le presse papier il est valable %{time}s!"
114
+ url: "L'URL a été copié dans le presse papier"
114
115
  help:
115
116
  name: "Aide"
117
+ url: "Pressez <u> pour copier l'URL"
116
118
  login: "Pressez <l> pour copier l'identifiant"
117
119
  password: "Pressez <p> pour copier le mot de passe"
118
120
  otp_code: "Pressez <o> pour copier le code OTP"
data/lib/mpw/cli.rb CHANGED
@@ -28,14 +28,13 @@ require 'mpw/mpw'
28
28
 
29
29
  module MPW
30
30
  class Cli
31
- # Constructor
32
- # @args: config -> the config
31
+ # @param config [Config]
33
32
  def initialize(config)
34
33
  @config = config
35
34
  end
36
35
 
37
36
  # Change a parameter int the config after init
38
- # @args: options -> param to change
37
+ # @param options [Hash] param to change
39
38
  def set_config(options)
40
39
  @config.setup(options)
41
40
 
@@ -46,7 +45,7 @@ module MPW
46
45
  end
47
46
 
48
47
  # Change the wallet path
49
- # @args: path -> the new path
48
+ # @param path [String] new path
50
49
  def set_wallet_path(path)
51
50
  @config.set_wallet_path(path, @wallet)
52
51
 
@@ -57,7 +56,7 @@ module MPW
57
56
  end
58
57
 
59
58
  # Create a new config file
60
- # @args: options -> set param
59
+ # @param options [Hash]
61
60
  def setup(options)
62
61
  options[:lang] = options[:lang] || Locale::Tag.parse(ENV['LANG']).to_simple.to_s[0..1]
63
62
 
@@ -74,7 +73,7 @@ module MPW
74
73
  end
75
74
 
76
75
  # Setup a new GPG key
77
- # @args: gpg_key -> the key name
76
+ # @param gpg_key [String] gpg key name
78
77
  def setup_gpg_key(gpg_key)
79
78
  return if @config.check_gpg_key?
80
79
 
@@ -106,7 +105,7 @@ module MPW
106
105
  'lang' => @config.lang,
107
106
  'gpg_key' => @config.gpg_key,
108
107
  'default_wallet' => @config.default_wallet,
109
- 'config_dir' => @config.config_dir,
108
+ 'wallet_dir' => @config.wallet_dir,
110
109
  'pinmode' => @config.pinmode,
111
110
  'gpg_exe' => @config.gpg_exe
112
111
  }
@@ -127,20 +126,28 @@ module MPW
127
126
 
128
127
  # Request the GPG password and decrypt the file
129
128
  def decrypt
130
- unless defined?(@mpw)
131
- @password = ask(I18n.t('display.gpg_password')) { |q| q.echo = false }
132
- @mpw = MPW.new(@config.gpg_key, @wallet_file, @password, @config.gpg_exe, @config.pinmode)
133
- end
129
+ if defined?(@mpw)
130
+ @mpw.read_data
131
+ else
132
+ begin
133
+ @mpw = MPW.new(@config.gpg_key, @wallet_file, nil, @config.gpg_exe, @config.pinmode)
134
+
135
+ @mpw.read_data
136
+ rescue
137
+ @password = ask(I18n.t('display.gpg_password')) { |q| q.echo = false }
138
+ @mpw = MPW.new(@config.gpg_key, @wallet_file, @password, @config.gpg_exe, @config.pinmode)
134
139
 
135
- @mpw.read_data
140
+ @mpw.read_data
141
+ end
142
+ end
136
143
  rescue => e
137
144
  puts "#{I18n.t('display.error')} #11: #{e}".red
138
145
  exit 2
139
146
  end
140
147
 
141
148
  # Format list on a table
142
- # @args: title -> the name of table
143
- # list -> array or hash
149
+ # @param title [String] name of table
150
+ # @param list an array or hash
144
151
  def table_list(title, list)
145
152
  length = { k: 0, v: 0 }
146
153
 
@@ -172,7 +179,7 @@ module MPW
172
179
  end
173
180
 
174
181
  # Format items on a table
175
- # @args: items -> an aray items
182
+ # @param items [Array]
176
183
  def table_items(items = [])
177
184
  group = '.'
178
185
  i = 1
@@ -180,16 +187,19 @@ module MPW
180
187
  data = { id: { length: 3, color: 'cyan' },
181
188
  host: { length: 9, color: 'yellow' },
182
189
  user: { length: 7, color: 'green' },
183
- protocol: { length: 9, color: 'white' },
184
- port: { length: 5, color: 'white' },
185
190
  otp: { length: 4, color: 'white' },
186
191
  comment: { length: 14, color: 'magenta' } }
187
192
 
188
193
  items.each do |item|
189
194
  data.each do |k, v|
190
- next if k == :id || k == :otp
191
-
192
- v[:length] = item.send(k.to_s).to_s.length + 3 if item.send(k.to_s).to_s.length >= v[:length]
195
+ case k
196
+ when :id, :otp
197
+ next
198
+ when :host
199
+ v[:length] = item.url.length + 3 if item.url.length >= v[:length]
200
+ else
201
+ v[:length] = item.send(k.to_s).to_s.length + 3 if item.send(k.to_s).to_s.length >= v[:length]
202
+ end
193
203
  end
194
204
  end
195
205
  data[:id][:length] = items.length.to_s.length + 2 if items.length.to_s.length > data[:id][:length]
@@ -232,16 +242,22 @@ module MPW
232
242
  data.each do |k, v|
233
243
  next if k == :id
234
244
 
235
- if k == :otp
236
- print '| '
245
+ print '| '
246
+
247
+ case k
248
+ when :otp
237
249
  item.otp ? (print ' X ') : 4.times { print ' ' }
238
250
 
239
- next
240
- end
251
+ when :host
252
+ print "#{item.protocol}://".light_black if item.protocol
253
+ print item.host.send(v[:color])
254
+ print ":#{item.port}".light_black if item.port
255
+ (v[:length] - item.url.to_s.length).times { print ' ' }
241
256
 
242
- print '| '
243
- print item.send(k.to_s).to_s.send(v[:color])
244
- (v[:length] - item.send(k.to_s).to_s.length).times { print ' ' }
257
+ else
258
+ print item.send(k.to_s).to_s.send(v[:color])
259
+ (v[:length] - item.send(k.to_s).to_s.length).times { print ' ' }
260
+ end
245
261
  end
246
262
  print "\n"
247
263
 
@@ -252,7 +268,7 @@ module MPW
252
268
  end
253
269
 
254
270
  # Display the query's result
255
- # @args: options -> the option to search
271
+ # @param options [Hash] the options to search
256
272
  def list(**options)
257
273
  result = @mpw.list(options)
258
274
 
@@ -264,8 +280,8 @@ module MPW
264
280
  end
265
281
 
266
282
  # Get an item when multiple choice
267
- # @args: items -> array of items
268
- # @rtrn: item
283
+ # @param items [Array] list of items
284
+ # @return [Item] an item
269
285
  def get_item(items)
270
286
  return items[0] if items.length == 1
271
287
 
@@ -276,8 +292,8 @@ module MPW
276
292
  end
277
293
 
278
294
  # Copy in clipboard the login and password
279
- # @args: item -> the item
280
- # clipboard -> enable clipboard
295
+ # @param item [Item]
296
+ # @param clipboard [Boolean] enable clipboard
281
297
  def clipboard(item, clipboard = true)
282
298
  # Security: force quit after 90s
283
299
  Thread.new do
@@ -292,6 +308,14 @@ module MPW
292
308
  when 'q', 'quit'
293
309
  break
294
310
 
311
+ when 'u', 'url'
312
+ if clipboard
313
+ Clipboard.copy(item.url)
314
+ puts I18n.t('form.clipboard.url').green
315
+ else
316
+ puts item.url
317
+ end
318
+
295
319
  when 'l', 'login'
296
320
  if clipboard
297
321
  Clipboard.copy(item.user)
@@ -324,6 +348,7 @@ module MPW
324
348
 
325
349
  else
326
350
  puts "----- #{I18n.t('form.clipboard.help.name')} -----".cyan
351
+ puts I18n.t('form.clipboard.help.url')
327
352
  puts I18n.t('form.clipboard.help.login')
328
353
  puts I18n.t('form.clipboard.help.password')
329
354
  puts I18n.t('form.clipboard.help.otp_code')
@@ -350,7 +375,7 @@ module MPW
350
375
  end
351
376
 
352
377
  # Display the wallet
353
- # @args: wallet -> the wallet name
378
+ # @param wallet [String] wallet name
354
379
  def get_wallet(wallet = nil)
355
380
  @wallet =
356
381
  if wallet.to_s.empty?
@@ -375,7 +400,7 @@ module MPW
375
400
  end
376
401
 
377
402
  # Add a new public key
378
- # args: key -> the key name or key file to add
403
+ # @param key [String] key name or key file to add
379
404
  def add_key(key)
380
405
  @mpw.add_key(key)
381
406
  @mpw.write_data
@@ -386,7 +411,7 @@ module MPW
386
411
  end
387
412
 
388
413
  # Add new public key
389
- # args: key -> the key name to delete
414
+ # @param key [String] key name to delete
390
415
  def delete_key(key)
391
416
  @mpw.delete_key(key)
392
417
  @mpw.write_data
@@ -397,10 +422,10 @@ module MPW
397
422
  end
398
423
 
399
424
  # Text editor interface
400
- # @args: template -> template name
401
- # item -> the item to edit
402
- # password -> disable field password
403
- # @rtrn: a hash with the value for an item
425
+ # @param template_name [String] template name
426
+ # @param item [Item] the item to edit
427
+ # @param password [Boolean] disable field password
428
+ # @return [Hash] the values for an item
404
429
  def text_editor(template_name, password = false, item = nil, **options)
405
430
  editor = ENV['EDITOR'] || 'nano'
406
431
  opts = {}
@@ -429,9 +454,9 @@ module MPW
429
454
  end
430
455
 
431
456
  # Form to add a new item
432
- # @args: password -> generate a random password
433
- # text_editor -> enable text editor mode
434
- # values -> hash with multiples value to set the item
457
+ # @param password [Boolean] generate a random password
458
+ # @param text_editor [Boolean] enable text editor mode
459
+ # @param values [Hash] multiples value to set the item
435
460
  def add(password = false, text_editor = false, **values)
436
461
  options = text_editor('add_form', password, nil, values) if text_editor
437
462
  item = Item.new(options)
@@ -448,15 +473,15 @@ module MPW
448
473
  end
449
474
 
450
475
  # Update an item
451
- # @args: password -> generate a random password
452
- # text_editor -> enable text editor mode
453
- # options -> the option to search
454
- # values -> hash with multiples value to set the item
476
+ # @param password [Boolean] generate a random password
477
+ # @param text_editor [Boolean] enable text editor mode
478
+ # @param options [Hash] the options to search
479
+ # @param values [Hash] multiples value to set the item
455
480
  def update(password = false, text_editor = false, options = {}, **values)
456
481
  items = @mpw.list(options)
457
482
 
458
483
  if items.empty?
459
- puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow
484
+ puts I18n.t('display.nothing')
460
485
  else
461
486
  table_items(items) if items.length > 1
462
487
 
@@ -476,12 +501,12 @@ module MPW
476
501
  end
477
502
 
478
503
  # Remove an item
479
- # @args: options -> the option to search
504
+ # @param options [Hash] the options to search
480
505
  def delete(**options)
481
506
  items = @mpw.list(options)
482
507
 
483
508
  if items.empty?
484
- puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow
509
+ puts I18n.t('display.nothing')
485
510
  else
486
511
  table_items(items)
487
512
 
@@ -500,8 +525,8 @@ module MPW
500
525
  end
501
526
 
502
527
  # Copy a password, otp, login
503
- # @args: clipboard -> enable clipboard
504
- # options -> the option to search
528
+ # @param clipboard [Boolean] enable clipboard
529
+ # @param options [Hash] the options to search
505
530
  def copy(clipboard = true, **options)
506
531
  items = @mpw.list(options)
507
532
 
@@ -517,9 +542,9 @@ module MPW
517
542
  puts "#{I18n.t('display.error')} #14: #{e}".red
518
543
  end
519
544
 
520
- # Export the items in a CSV file
521
- # @args: file -> the destination file
522
- # options -> option to search
545
+ # Export the items in an yaml file
546
+ # @param file [String] the path of destination file
547
+ # @param options [Hash] options to search
523
548
  def export(file, options)
524
549
  file = 'export-mpw.yml' if file.to_s.empty?
525
550
  items = @mpw.list(options)
@@ -549,8 +574,8 @@ module MPW
549
574
  puts "#{I18n.t('display.error')} #17: #{e}".red
550
575
  end
551
576
 
552
- # Import items from a YAML file
553
- # @args: file -> the import file
577
+ # Import items from an yaml file
578
+ # @param file [String] path of import file
554
579
  def import(file)
555
580
  raise I18n.t('form.import.file_empty') if file.to_s.empty?
556
581
  raise I18n.t('form.import.file_not_exist') unless File.exist?(file)
data/lib/mpw/config.rb CHANGED
@@ -35,8 +35,7 @@ module MPW
35
35
  attr_accessor :password
36
36
  attr_accessor :pinmode
37
37
 
38
- # Constructor
39
- # @args: config_file -> the specify config file
38
+ # @param config_file [String] path of config file
40
39
  def initialize(config_file = nil)
41
40
  @config_file = config_file
42
41
  @config_dir =
@@ -52,19 +51,20 @@ module MPW
52
51
  end
53
52
 
54
53
  # Create a new config file
55
- # @args: options -> hash with values
56
- # @rtrn: true if le config file is create
54
+ # @param options [Hash] the value to set the config file
57
55
  def setup(**options)
58
56
  gpg_key = options[:gpg_key] || @gpg_key
59
57
  lang = options[:lang] || @lang
60
58
  wallet_dir = options[:wallet_dir] || @wallet_dir
61
59
  default_wallet = options[:default_wallet] || @default_wallet
62
60
  gpg_exe = options[:gpg_exe] || @gpg_exe
63
- pinmode = options[:pinmode] || @pinmode
64
- password = { numeric: true,
65
- alpha: true,
66
- special: false,
67
- length: 16 }
61
+ pinmode = options.key?(:pinmode) ? options[:pinmode] : @pinmode
62
+ password = {
63
+ numeric: true,
64
+ alpha: true,
65
+ special: false,
66
+ length: 16
67
+ }
68
68
 
69
69
  %w[numeric special alpha length].each do |k|
70
70
  if options.key?("pwd_#{k}".to_sym)
@@ -99,11 +99,10 @@ module MPW
99
99
  end
100
100
 
101
101
  # Setup a new gpg key
102
- # @args: password -> the GPG key password
103
- # name -> the name of user
104
- # length -> length of the GPG key
105
- # expire -> the time of expire to GPG key
106
- # @rtrn: true if the GPG key is create, else false
102
+ # @param password [String] gpg key password
103
+ # @param name [String] the name of user
104
+ # @param length [Integer] length of the gpg key
105
+ # @param expire [Integer] time of expire to gpg key
107
106
  def setup_gpg_key(password, name, length = 4096, expire = 0)
108
107
  raise I18n.t('error.config.genkey_gpg.name') if name.to_s.empty?
109
108
  raise I18n.t('error.config.genkey_gpg.password') if password.to_s.empty?
@@ -137,7 +136,7 @@ module MPW
137
136
  @default_wallet = config['default_wallet']
138
137
  @gpg_exe = config['gpg_exe']
139
138
  @password = config['password'] || {}
140
- @pinmode = config['pinmode']
139
+ @pinmode = config['pinmode'] || false
141
140
 
142
141
  raise if @gpg_key.empty? || @wallet_dir.empty?
143
142
 
@@ -147,7 +146,7 @@ module MPW
147
146
  end
148
147
 
149
148
  # Check if private key exist
150
- # @rtrn: true if the key exist, else false
149
+ # @return [Boolean] true if the key exist, else false
151
150
  def check_gpg_key?
152
151
  ctx = GPGME::Ctx.new
153
152
  ctx.each_key(@gpg_key, true) do
@@ -158,8 +157,8 @@ module MPW
158
157
  end
159
158
 
160
159
  # Change the path of one wallet
161
- # @args: path -> the new directory path
162
- # wallet -> the wallet name
160
+ # @param path [String]new directory path
161
+ # @param wallet [String] wallet name
163
162
  def set_wallet_path(path, wallet)
164
163
  path = @wallet_dir if path == 'default'
165
164
 
data/lib/mpw/item.rb CHANGED
@@ -31,10 +31,7 @@ module MPW
31
31
  attr_accessor :last_edit
32
32
  attr_accessor :created
33
33
 
34
- # Constructor
35
- # Create a new item
36
- # @args: options -> a hash of parameter
37
- # raise an error if the hash hasn't the key name
34
+ # @param options [Hash] the option :host is required
38
35
  def initialize(**options)
39
36
  if !options.key?(:host) || options[:host].to_s.empty?
40
37
  raise I18n.t('error.update.host_empty')
@@ -54,7 +51,7 @@ module MPW
54
51
  end
55
52
 
56
53
  # Update the item
57
- # @args: options -> a hash of parameter
54
+ # @param options [Hash]
58
55
  def update(**options)
59
56
  if options.key?(:host) && options[:host].to_s.empty?
60
57
  raise I18n.t('error.update.host_empty')
@@ -84,6 +81,17 @@ module MPW
84
81
  @last_edit = nil
85
82
  end
86
83
 
84
+ # Return data on url format
85
+ # @return [String] an url
86
+ def url
87
+ url = ''
88
+ url += "#{@protocol}://" if @protocol
89
+ url += @host
90
+ url += ":#{@port}" if @port
91
+
92
+ url
93
+ end
94
+
87
95
  def empty?
88
96
  @id.to_s.empty?
89
97
  end
@@ -95,6 +103,7 @@ module MPW
95
103
  private
96
104
 
97
105
  # Generate an random id
106
+ # @return [String] random string
98
107
  def generate_id
99
108
  [*('A'..'Z'), *('a'..'z'), *('0'..'9')].sample(16).join
100
109
  end