retrieve method

Future<Map<String, String>> retrieve()

Retrieves securely stored data.

Falls back to the pre-0.2.1 cipher for existing files and transparently re-encrypts them with the current scheme. Returns an empty map if no data is stored or decryption fails.

Implementation

Future<Map<String, String>> retrieve() async {
  if (!_credentialsFile.existsSync()) {
    return {};
  }

  final List<int> key;
  final List<int> encrypted;
  try {
    key = await _getMachineKey();
    encrypted = await _credentialsFile.readAsBytes();
  } catch (_) {
    // Corrupt .key or unreadable creds file: honor the documented
    // contract (empty map on failure) instead of crashing every command.
    _warnUnreadable();
    return {};
  }

  final current = _tryDecode(() => _decrypt(encrypted, key));
  if (current != null) return current;

  final legacy = _tryDecode(() => _decryptLegacy(encrypted, key));
  if (legacy != null) {
    // Upgrade the on-disk format to the current cipher. Best-effort: the
    // data decrypted fine, so a failed rewrite (e.g. read-only file) must
    // not turn a successful read into an error.
    try {
      await store(legacy);
    } catch (_) {
      // Keep serving the legacy format until the file is writable again.
    }
    return legacy;
  }

  _warnUnreadable();
  return {};
}