migrateLegacySecretFiles static method
Moves the pre-1.8.0 macOS clear-text secret files at paths (most
recent location first, .tmp siblings included) into the Keychain and
destroys them: every entry is written, read back, and only then are the
files overwritten and deleted. Call once at startup on macOS, after
useMacosKeychainService and before anything asks for a secret.
Throws SecureStorageException when the store fails, in which case no file is touched and the next launch tries again. Until then, and as long as the report says LegacySecretFileReport.unresolved, masterKey refuses to generate a key, since a file may still hold the real one. Any master key cached in this process is dropped either way.
Implementation
static Future<LegacySecretFileReport> migrateLegacySecretFiles(
List<String> paths,
) async {
final inFlight = _masterKeyLoading;
if (inFlight != null) {
// A load started before the move would cache what the store held
// before it; let it finish, then forget it below.
await inFlight.then((_) {}, onError: (_) {});
}
_legacySecretFilesPending = true;
try {
final report = await LegacySecretFileMigration(
const _MigrationStore(),
).run(paths);
// A file left in place with a secret the store could not take over,
// unreadable or naming another key, keeps the block: "no old file" and
// "old file not resolved" are not the same state.
_legacySecretFilesPending = report.unresolved;
return report;
} finally {
_cachedMasterKey = null;
_masterKeyLoading = null;
}
}