|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to KSafe will be documented in this file. |
| 4 | + |
| 5 | +## [1.3.0] - 2025-12-31 |
| 6 | + |
| 7 | +### Added |
| 8 | + |
| 9 | +#### Standalone Biometric Authentication |
| 10 | +- **New `verifyBiometric()` suspend function** - Coroutine-based biometric verification |
| 11 | +- **New `verifyBiometricDirect()` callback function** - Non-blocking biometric verification for any context |
| 12 | +- **Biometric authentication is now decoupled from storage** - Use it to protect any action (API calls, navigation, data display), not just KSafe operations |
| 13 | + |
| 14 | +#### Authorization Duration Caching |
| 15 | +- **New `BiometricAuthorizationDuration` data class** for configuring cached authentication: |
| 16 | + ```kotlin |
| 17 | + data class BiometricAuthorizationDuration( |
| 18 | + val duration: Long, // Duration in milliseconds |
| 19 | + val scope: String? = null // Optional scope identifier |
| 20 | + ) |
| 21 | + ``` |
| 22 | +- **Duration caching** - Avoid repeated biometric prompts by caching successful auth for a specified duration |
| 23 | +- **Scoped authorization** - Different scopes maintain separate auth timestamps for fine-grained control |
| 24 | +- **Recommended pattern**: Use `viewModelScope.hashCode().toString()` for ViewModel-scoped auth that auto-invalidates when the ViewModel is recreated |
| 25 | + |
| 26 | +#### Authorization Management |
| 27 | +- **New `clearBiometricAuth()` function** - Force re-authentication by clearing cached auth |
| 28 | + - `clearBiometricAuth()` - Clear all cached authorizations |
| 29 | + - `clearBiometricAuth(scope)` - Clear only a specific scope |
| 30 | + |
| 31 | +### Changed |
| 32 | +- **Removed `useBiometrics` parameter** from all storage APIs (`get`, `put`, `getDirect`, `putDirect`) |
| 33 | +- Biometric verification is now a separate step you control explicitly |
| 34 | +- **iOS thread safety improvements** - Biometric callbacks now always execute on Main thread |
| 35 | + |
| 36 | +### Migration from 1.2.x |
| 37 | + |
| 38 | +#### Before (1.2.x) |
| 39 | +```kotlin |
| 40 | +// Biometrics tied to storage |
| 41 | +ksafe.put("key", value, useBiometrics = true) |
| 42 | +val data = ksafe.get("key", default, useBiometrics = true) |
| 43 | +``` |
| 44 | + |
| 45 | +#### After (1.3.0) |
| 46 | +```kotlin |
| 47 | +// Biometrics as a separate verification step |
| 48 | +ksafe.verifyBiometricDirect("Authenticate to save") { success -> |
| 49 | + if (success) { |
| 50 | + ksafe.putDirect("key", value) |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +// Or with suspend function |
| 55 | +if (ksafe.verifyBiometric("Authenticate to read")) { |
| 56 | + val data = ksafe.get("key", default) |
| 57 | +} |
| 58 | + |
| 59 | +// With duration caching (60 seconds, scoped to ViewModel) |
| 60 | +ksafe.verifyBiometricDirect( |
| 61 | + reason = "Authenticate", |
| 62 | + authorizationDuration = BiometricAuthorizationDuration( |
| 63 | + duration = 60_000L, |
| 64 | + scope = viewModelScope.hashCode().toString() |
| 65 | + ) |
| 66 | +) { success -> |
| 67 | + if (success) { /* ... */ } |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +### Benefits of New Architecture |
| 72 | +- **Full control** over when biometric prompts appear |
| 73 | +- **Reusable** - Same biometric helper protects any action |
| 74 | +- **Flexible caching** - Avoid prompt fatigue with duration caching |
| 75 | +- **Scoped invalidation** - Auth tied to ViewModel lifecycle or custom scopes |
| 76 | +- **Cleaner separation** - Storage and authentication are independent concerns |
| 77 | + |
| 78 | +--- |
| 79 | + |
| 80 | +## [1.2.0] - 2025-01-15 |
| 81 | + |
| 82 | +### Added |
| 83 | +- **Hybrid "Hot Cache" Architecture** - Zero-latency UI reads with async preloading |
| 84 | +- **Memory Security Policy** - Choose between `ENCRYPTED` (max security) or `PLAIN_TEXT` (max performance) |
| 85 | +- **Nullable value support** - Correctly store and retrieve `null` values |
| 86 | +- **Multiple KSafe instances** - Create separate instances with different file names |
| 87 | +- **JVM/Desktop support** - Full support alongside Android and iOS |
| 88 | +- **KSafeConfig** - Configurable encryption parameters (key size) |
| 89 | +- **Lazy loading option** - Defer data loading until first access |
| 90 | + |
| 91 | +### Changed |
| 92 | +- `getDirect()` now performs atomic memory lookup (O(1)) instead of blocking disk read |
| 93 | +- `putDirect()` uses optimistic updates - immediate cache update with background persistence |
| 94 | +- Eager preloading on initialization by default (use `lazyLoad = true` to defer) |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +## [1.1.0] - 2024-12-01 |
| 99 | + |
| 100 | +### Added |
| 101 | +- Initial release with encrypted persistence |
| 102 | +- Property delegation (`by ksafe(defaultValue)`) |
| 103 | +- Compose state support (`by ksafe.mutableStateOf(defaultValue)`) |
| 104 | +- Android Keystore and iOS Keychain integration |
| 105 | +- Suspend and Direct APIs |
0 commit comments