Module: Lich::Common::CLI::CLIOrchestration

Defined in:
documented/common/cli/cli_orchestration.rb

Overview

Provides orchestration for command line interface operations.

Class Method Summary collapse

Class Method Details

.check_conversion_needed_for_loginvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Checks if conversion is required before a login attempt.



51
52
53
54
55
56
57
# File 'documented/common/cli/cli_orchestration.rb', line 51

def self.
  # Check if conversion is required
  if Lich::Common::CLI::CLIConversion.conversion_needed?(DATA_DIR)
    Lich::Common::CLI::CLIConversion.print_conversion_help_message
    exit 1
  end
end

.executevoid

This method returns an undefined value.

Executes the command line interface orchestration.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'documented/common/cli/cli_orchestration.rb', line 20

def self.execute
  ActiveSessionsQuery.execute

  ARGV.each do |arg|
    case arg
    when /^--change-account-password$/, /^-cap$/
      
    when /^--add-account$/, /^-aa$/
      
    when /^--change-master-password$/, /^-cmp$/
      handle_change_master_password
    when /^--recover-master-password$/, /^-rmp$/
      handle_recover_master_password
    when /^--convert-entries$/
      handle_convert_entries
    when /^--change-encryption-mode$/, /^-cem$/
      handle_change_encryption_mode
    end
  end

  # Check for conversion needed before login attempt
  # This is not an early-exit operation - it detects a precondition for login
  if ARGV.include?('--login')
    
  end
end

.handle_add_accountInteger

Handles the addition of a new account via command line arguments.

Parameters:

  • account (String)

    the account to be added

  • password (String)

    the password for the new account

  • frontend (String, nil)

    optional frontend specification

Returns:

  • (Integer)

    exit status code



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'documented/common/cli/cli_orchestration.rb', line 86

def self.
  idx = ARGV.index { |a| a =~ /^--add-account$|^-aa$/ }
   = ARGV[idx + 1]
  password = ARGV[idx + 2]

  if .nil? || password.nil?
    lich_script = File.join(LICH_DIR, 'lich.rbw')
    $stdout.puts 'error: Missing required arguments'
    $stdout.puts "Usage: ruby #{lich_script} --add-account ACCOUNT PASSWORD [--frontend FRONTEND]"
    $stdout.puts "   or: ruby #{lich_script} -aa ACCOUNT PASSWORD [--frontend FRONTEND]"
    exit 1
  end

  # Check if YAML file exists; if not, check for DAT and auto-convert to plaintext
  yaml_file = Lich::Common::Authentication::EntryStore.yaml_file_path(DATA_DIR)
  unless File.exist?(yaml_file)
    if Lich::Common::CLI::CLIConversion.conversion_needed?(DATA_DIR)
      $stdout.puts ''
      $stdout.puts '=' * 80
      $stdout.puts 'WARNING: No YAML entry file found. Legacy entry.dat detected.'
      $stdout.puts 'Creating plaintext YAML file to support this operation.'
      $stdout.puts '=' * 80
      $stdout.puts ''
      $stdout.puts 'SECURITY NOTICE: Plaintext storage is not recommended except for'
      $stdout.puts 'accessibility requirements. Passwords will be stored in clear text.'
      $stdout.puts ''
      $stdout.puts 'To upgrade encryption later, use:'
      $stdout.puts "  ruby #{File.join(LICH_DIR, 'lich.rbw')} --change-encryption-mode enhanced"
      $stdout.puts '  or: -cem enhanced'
      $stdout.puts '=' * 80
      $stdout.puts ''

      # Perform plaintext conversion
      success = Lich::Common::CLI::CLIConversion.convert(DATA_DIR, :plaintext)
      unless success
        $stdout.puts 'error: Failed to create YAML file from legacy data.'
        exit 1
      end
      # Continue with add-account operation below
    end
    # No DAT file either - CLIPassword.add_account will create new YAML
  end

  frontend = ARGV[ARGV.index('--frontend') + 1] if ARGV.include?('--frontend')
  exit Lich::Common::Authentication::CLIPassword.(, password, frontend)
end

.handle_change_account_passwordInteger

Handles the change of an account password via command line arguments.

Parameters:

  • account (String)

    the account whose password is to be changed

  • new_password (String)

    the new password for the account

Returns:

  • (Integer)

    exit status code



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'documented/common/cli/cli_orchestration.rb', line 64

def self.
  idx = ARGV.index { |a| a =~ /^--change-account-password$|^-cap$/ }
   = ARGV[idx + 1]
  new_password = ARGV[idx + 2]

  if .nil? || new_password.nil?
    lich_script = File.join(LICH_DIR, 'lich.rbw')
    $stdout.puts 'error: Missing required arguments'
    $stdout.puts "Usage: ruby #{lich_script} --change-account-password ACCOUNT NEWPASSWORD"
    $stdout.puts "   or: ruby #{lich_script} -cap ACCOUNT NEWPASSWORD"
    exit 1
  end

  exit Lich::Common::Authentication::CLIPassword.(, new_password)
end

.handle_change_encryption_modeInteger

Handles the change of the encryption mode via command line arguments.

Parameters:

  • mode_arg (String)

    the new encryption mode to set

Returns:

  • (Integer)

    exit status code



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'documented/common/cli/cli_orchestration.rb', line 225

def self.handle_change_encryption_mode
  idx = ARGV.index { |a| a =~ /^--change-encryption-mode$|^-cem$/ }
  mode_arg = ARGV[idx + 1]

  if mode_arg.nil?
    lich_script = File.join(LICH_DIR, 'lich.rbw')
    $stdout.puts 'error: Missing encryption mode'
    $stdout.puts "Usage: ruby #{lich_script} --change-encryption-mode MODE [--master-password PASSWORD]"
    $stdout.puts "       ruby #{lich_script} -cem MODE [-mp PASSWORD]"
    $stdout.puts 'Modes: plaintext, standard, enhanced'
    exit 1
  end

  new_mode = mode_arg.to_sym

  # Check for optional master password (for Enhanced mode, if automating)
  mp_index = ARGV.index('--master-password') || ARGV.index('-mp')
  master_password = ARGV[mp_index + 1] if mp_index

  exit Lich::Common::CLI::EncryptionModeChange.change_mode(new_mode, master_password)
end

.handle_change_master_passwordInteger

Handles the change of the master password via command line arguments.

Parameters:

  • old_password (String)

    the current master password

  • new_password (String, nil)

    the new master password (optional)

Returns:

  • (Integer)

    exit status code



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'documented/common/cli/cli_orchestration.rb', line 138

def self.handle_change_master_password
  idx = ARGV.index { |a| a =~ /^--change-master-password$|^-cmp$/ }
  old_password = ARGV[idx + 1]
  new_password = ARGV[idx + 2]

  if old_password.nil?
    lich_script = File.join(LICH_DIR, 'lich.rbw')
    $stdout.puts 'error: Missing required arguments'
    $stdout.puts "Usage: ruby #{lich_script} --change-master-password OLDPASSWORD [NEWPASSWORD]"
    $stdout.puts "   or: ruby #{lich_script} -cmp OLDPASSWORD [NEWPASSWORD]"
    $stdout.puts 'Note: If NEWPASSWORD is not provided, you will be prompted for confirmation'
    exit 1
  end

  exit Lich::Common::Authentication::CLIPassword.change_master_password(old_password, new_password)
end

.handle_convert_entriesInteger

Handles the conversion of entries to a specified encryption mode.

Parameters:

  • encryption_mode_str (String)

    the encryption mode to convert to (e.g., "plaintext", "standard", "enhanced")

Returns:

  • (Integer)

    exit status code



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'documented/common/cli/cli_orchestration.rb', line 171

def self.handle_convert_entries
  idx = ARGV.index('--convert-entries')
  encryption_mode_str = ARGV[idx + 1]

  if encryption_mode_str.nil?
    lich_script = File.join(LICH_DIR, 'lich.rbw')
    $stdout.puts 'error: Missing required argument'
    $stdout.puts "Usage: ruby #{lich_script} --convert-entries [plaintext|standard|enhanced]"
    exit 1
  end

  unless %w[plaintext standard enhanced].include?(encryption_mode_str)
    $stdout.puts "error: Invalid encryption mode: #{encryption_mode_str}"
    $stdout.puts 'Valid modes: plaintext, standard, enhanced'
    exit 1
  end

  # For enhanced mode, prompt for master password and store in keychain before conversion
  # This way migrate_from_legacy will find it in keychain and not try to show GUI dialog
  if encryption_mode_str == 'enhanced'
    master_password = Lich::Common::Authentication::CLIPassword.prompt_and_confirm_password('Enter new master password for enhanced encryption')
    if master_password.nil?
      puts 'error: Master password creation cancelled'
      exit 1
    end

    # Store password in keychain so ensure_master_password_exists finds it
    require_relative '../gui/master_password_manager'
    stored = Lich::Common::GUI::MasterPasswordManager.store_master_password(master_password)
    unless stored
      puts 'error: Failed to store master password in keychain'
      exit 1
    end
  end

  # Perform conversion
  success = Lich::Common::CLI::CLIConversion.convert(
    DATA_DIR,
    encryption_mode_str
  )

  if success
    $stdout.puts 'Conversion completed successfully!'
    exit 0
  else
    $stdout.puts 'Conversion failed. Please check the logs for details.'
    exit 1
  end
end

.handle_recover_master_passwordInteger

Handles the recovery of the master password via command line arguments.

Parameters:

  • new_password (String, nil)

    the new master password (optional)

Returns:

  • (Integer)

    exit status code



159
160
161
162
163
164
165
# File 'documented/common/cli/cli_orchestration.rb', line 159

def self.handle_recover_master_password
  idx = ARGV.index { |a| a =~ /^--recover-master-password$|^-rmp$/ }
  new_password = ARGV[idx + 1]

  # new_password is optional - if not provided, user will be prompted interactively
  exit Lich::Common::Authentication::CLIPassword.recover_master_password(new_password)
end