#51924: fix: lazily initialize safeStorage async encryptor
Backport of #50419
See that PR for details.
Fixes #51759.
On 42-x-y, the SafeStorage constructor registers a browser observer that requests the async encryptor on app-ready, and isAsyncEncryptionAvailable() synchronously returns is_available_. Because the encryptor arrives via an asynchronous keychain round-trip, calling isAsyncEncryptionAvailable() shortly after ready returns false, and any encryptStringAsync()/decryptStringAsync() call queued before the encryptor arrives crashes the process — OnOsCryptReady fires from a posted task without a V8 HandleScope and the pending-encrypt path creates handles (Buffer::Copy, Promise::Resolve).
Verified: the repro from #51759 reproduces the false + SIGSEGV on v42.2.0 and passes on v43.0.0-beta.1, which contains this change.
Notes: Fixed safeStorage.isAsyncEncryptionAvailable() incorrectly reporting false shortly after the app ready event, and a crash when calling safeStorage.encryptStringAsync() or safeStorage.decryptStringAsync() before async encryption initialization completed. safeStorage.isAsyncEncryptionAvailable() now returns a Promise as documented.
Backport Information
Backported from
#50419: fix: lazily initialize safeStorage async encryptorSemver Impact
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron