mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-05 07:14:15 -04:00
Cleanup NativeVaultManager bridge (#1340)
This commit is contained in:
committed by
Leendert de Borst
parent
95a5391589
commit
52b60e07d2
@@ -63,7 +63,7 @@ class NativeVaultManager(reactContext: ReactApplicationContext) :
|
||||
const val PIN_SETUP_REQUEST_CODE = 1002
|
||||
|
||||
/**
|
||||
* Static holder for the pending promise from showPinUnlockUI.
|
||||
* Static holder for the pending promise from showPinUnlock.
|
||||
* This allows MainActivity to resolve/reject the promise directly without
|
||||
* depending on React context availability.
|
||||
*/
|
||||
@@ -71,7 +71,7 @@ class NativeVaultManager(reactContext: ReactApplicationContext) :
|
||||
var pendingActivityResultPromise: Promise? = null
|
||||
|
||||
/**
|
||||
* Static holder for the pending promise from showNativePinSetup.
|
||||
* Static holder for the pending promise from showPinSetup.
|
||||
* This allows MainActivity to resolve/reject the promise directly without
|
||||
* depending on React context availability.
|
||||
*/
|
||||
@@ -1287,47 +1287,6 @@ class NativeVaultManager(reactContext: ReactApplicationContext) :
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configured PIN length.
|
||||
* @param promise The promise to resolve.
|
||||
*/
|
||||
@ReactMethod
|
||||
override fun getPinLength(promise: Promise) {
|
||||
try {
|
||||
val length = vaultStore.getPinLength()
|
||||
promise.resolve(length)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error getting PIN length", e)
|
||||
promise.reject("ERR_GET_PIN_LENGTH", "Failed to get PIN length: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup PIN unlock.
|
||||
* Gets the vault encryption key from memory (vault must be unlocked).
|
||||
* @param pin The PIN to set.
|
||||
* @param promise The promise to resolve.
|
||||
*/
|
||||
@ReactMethod
|
||||
override fun setupPin(pin: String, promise: Promise) {
|
||||
vaultStore.getEncryptionKey(object : net.aliasvault.app.vaultstore.interfaces.CryptoOperationCallback {
|
||||
override fun onSuccess(result: String) {
|
||||
try {
|
||||
vaultStore.setupPin(pin, result)
|
||||
promise.resolve(null)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error setting up PIN", e)
|
||||
promise.reject("ERR_SETUP_PIN", "Failed to setup PIN: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(error: Exception) {
|
||||
Log.e(TAG, "Error getting encryption key for PIN setup", error)
|
||||
promise.reject("ERR_SETUP_PIN", "Failed to get encryption key: ${error.message}", error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Show native PIN setup UI.
|
||||
* Launches the native PinUnlockActivity in setup mode.
|
||||
@@ -1368,38 +1327,6 @@ class NativeVaultManager(reactContext: ReactApplicationContext) :
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock with PIN.
|
||||
* @param pin The PIN to unlock with.
|
||||
* @param promise The promise to resolve.
|
||||
*/
|
||||
@ReactMethod
|
||||
override fun unlockWithPin(pin: String, promise: Promise) {
|
||||
try {
|
||||
val vaultEncryptionKey = vaultStore.unlockWithPin(pin)
|
||||
promise.resolve(vaultEncryptionKey)
|
||||
} catch (e: net.aliasvault.app.vaultstore.PinUnlockException) {
|
||||
// Handle PinUnlockException with proper error codes and English messages for React Native
|
||||
Log.e(TAG, "PIN unlock error: ${e.errorCode}", e)
|
||||
when (e) {
|
||||
is net.aliasvault.app.vaultstore.PinUnlockException.NotConfigured -> {
|
||||
promise.reject("PIN_NOT_CONFIGURED", "PIN unlock is not configured", null)
|
||||
}
|
||||
is net.aliasvault.app.vaultstore.PinUnlockException.Locked -> {
|
||||
promise.reject("PIN_LOCKED", "PIN locked after too many failed attempts", null)
|
||||
}
|
||||
is net.aliasvault.app.vaultstore.PinUnlockException.IncorrectPin -> {
|
||||
val message = "Incorrect PIN. ${e.attemptsRemaining} attempts remaining"
|
||||
promise.reject("INCORRECT_PIN", message, null)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// Fallback for any other errors
|
||||
Log.e(TAG, "Error unlocking with PIN", e)
|
||||
promise.reject("PIN_UNLOCK_ERROR", "Failed to unlock with PIN: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable PIN unlock and remove all stored data.
|
||||
* @param promise The promise to resolve.
|
||||
@@ -1416,7 +1343,7 @@ class NativeVaultManager(reactContext: ReactApplicationContext) :
|
||||
}
|
||||
|
||||
/**
|
||||
* Show native PIN unlock UI.
|
||||
* Show PIN unlock UI.
|
||||
* This presents a native PIN unlock screen modally and handles the unlock flow.
|
||||
* On success, the vault is unlocked and the encryption key is stored in memory.
|
||||
* On cancel or error, the promise is rejected.
|
||||
@@ -1424,7 +1351,7 @@ class NativeVaultManager(reactContext: ReactApplicationContext) :
|
||||
* @param promise The promise to resolve on success or reject on error/cancel.
|
||||
*/
|
||||
@ReactMethod
|
||||
override fun showPinUnlockUI(promise: Promise) {
|
||||
override fun showPinUnlock(promise: Promise) {
|
||||
val activity = currentActivity
|
||||
if (activity == null) {
|
||||
promise.reject("NO_ACTIVITY", "No activity available", null)
|
||||
|
||||
@@ -162,7 +162,7 @@ export default function VaultUnlockSettingsScreen() : React.ReactNode {
|
||||
const handleEnablePin = useCallback(async () : Promise<void> => {
|
||||
try {
|
||||
// Launch native PIN setup UI
|
||||
await NativeVaultManager.showNativePinSetup();
|
||||
await NativeVaultManager.showPinSetup();
|
||||
|
||||
// PIN setup successful - now disable biometrics if it was enabled
|
||||
if (isBiometricsEnabled) {
|
||||
@@ -308,8 +308,7 @@ export default function VaultUnlockSettingsScreen() : React.ReactNode {
|
||||
</View>
|
||||
<ThemedText style={styles.helpText}>
|
||||
{t('settings.vaultUnlockSettings.biometricHelp', {
|
||||
keystore: Platform.OS === 'ios' ? t('settings.vaultUnlockSettings.keystoreIOS') : t('settings.vaultUnlockSettings.keystoreAndroid'),
|
||||
biometric: biometricDisplayName
|
||||
keystore: Platform.OS === 'ios' ? t('settings.vaultUnlockSettings.keystoreIOS') : t('settings.vaultUnlockSettings.keystoreAndroid')
|
||||
})}
|
||||
</ThemedText>
|
||||
{!hasBiometrics && (
|
||||
|
||||
@@ -66,7 +66,7 @@ export default function UnlockScreen() : React.ReactNode {
|
||||
* Show native PIN unlock UI
|
||||
* This will handle the unlock internally and store the encryption key
|
||||
*/
|
||||
await NativeVaultManager.showPinUnlockUI();
|
||||
await NativeVaultManager.showPinUnlock();
|
||||
|
||||
/*
|
||||
* Check if the vault is ready
|
||||
|
||||
@@ -292,11 +292,10 @@
|
||||
"biometricEnabled": "{{biometric}} is now successfully enabled",
|
||||
"biometricNotAvailable": "{{biometric}} Not Available",
|
||||
"biometricDisabledMessage": "{{biometric}} is disabled for AliasVault. In order to use it, please enable it in your device settings first.",
|
||||
"biometricHelp": "Your vault decryption key will be securely stored on your local device in the {{keystore}} and can be accessed securely with {{biometric}}.",
|
||||
"biometricHelp": "Use biometrics to unlock your vault, which is secured by the {{keystore}}.",
|
||||
"biometricUnavailableHelp": "{{biometric}} is not available. Tap to open settings and/or go to your device settings to enable and configure it.",
|
||||
"pin": "PIN Code",
|
||||
"pinDescription": "Use a custom PIN code to unlock your vault quickly",
|
||||
"pinHelp": "Your vault decryption key will be encrypted with your PIN and stored securely on your device.",
|
||||
"pinDescription": "Use a custom PIN code to unlock your vault more quickly.",
|
||||
"pinEnabled": "PIN unlock enabled successfully",
|
||||
"pinDisabled": "PIN unlock has been disabled",
|
||||
"setupPin": "Setup PIN",
|
||||
|
||||
@@ -261,28 +261,16 @@
|
||||
[vaultManager isPinEnabled:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
- (void)getPinLength:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager getPinLength:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
- (void)setupPin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager setupPin:pin resolver:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
- (void)unlockWithPin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager unlockWithPin:pin resolver:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
- (void)removeAndDisablePin:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager removeAndDisablePin:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
- (void)showPinUnlockUI:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager showPinUnlockUI:resolve rejecter:reject];
|
||||
- (void)showPinUnlock:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager showPinUnlock:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
- (void)showNativePinSetup:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager showNativePinSetup:resolve rejecter:reject];
|
||||
- (void)showPinSetup:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
||||
[vaultManager showPinSetup:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -756,58 +756,12 @@ public class VaultManager: NSObject {
|
||||
resolve(vaultStore.isPinEnabled())
|
||||
}
|
||||
|
||||
@objc
|
||||
func getPinLength(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
if let length = vaultStore.getPinLength() {
|
||||
resolve(length)
|
||||
} else {
|
||||
resolve(nil)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func getPinFailedAttempts(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
resolve(vaultStore.getPinFailedAttempts())
|
||||
}
|
||||
|
||||
@objc
|
||||
func setupPin(_ pin: String,
|
||||
resolver resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
do {
|
||||
try vaultStore.setupPin(pin)
|
||||
resolve(nil)
|
||||
} catch {
|
||||
reject("SETUP_PIN_ERROR", "Failed to setup PIN: \(error.localizedDescription)", error)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func unlockWithPin(_ pin: String,
|
||||
resolver resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
do {
|
||||
let vaultEncryptionKey = try vaultStore.unlockWithPin(pin)
|
||||
resolve(vaultEncryptionKey)
|
||||
} catch let error as PinUnlockError {
|
||||
// Handle PinUnlockError with proper error codes and localized messages
|
||||
switch error {
|
||||
case .notConfigured:
|
||||
reject("PIN_NOT_CONFIGURED", "PIN unlock is not configured", nil)
|
||||
case .locked:
|
||||
reject("PIN_LOCKED", "PIN locked after too many failed attempts", nil)
|
||||
case .incorrectPin(let attemptsRemaining):
|
||||
let message = "Incorrect PIN. \(attemptsRemaining) attempts remaining"
|
||||
reject("INCORRECT_PIN", message, nil)
|
||||
}
|
||||
} catch {
|
||||
// Fallback for any other errors
|
||||
reject("PIN_UNLOCK_ERROR", error.localizedDescription, error)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func resetPinFailedAttempts(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
@@ -827,7 +781,7 @@ public class VaultManager: NSObject {
|
||||
}
|
||||
|
||||
@objc
|
||||
func showPinUnlockUI(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
func showPinUnlock(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else {
|
||||
@@ -885,7 +839,7 @@ public class VaultManager: NSObject {
|
||||
}
|
||||
|
||||
@objc
|
||||
func showNativePinSetup(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
func showPinSetup(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else {
|
||||
|
||||
@@ -104,7 +104,7 @@ public struct PinSetupView: View {
|
||||
await viewModel.submitPin()
|
||||
}
|
||||
}) {
|
||||
Text(String(localized: "common_next", bundle: locBundle))
|
||||
Text(String(localized: "next", bundle: locBundle))
|
||||
.font(.system(size: 16, weight: .semibold))
|
||||
.foregroundColor(.white)
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
@@ -92,12 +92,9 @@ export interface Spec extends TurboModule {
|
||||
|
||||
// PIN unlock methods
|
||||
isPinEnabled(): Promise<boolean>;
|
||||
getPinLength(): Promise<number | null>;
|
||||
unlockWithPin(pin: string): Promise<string>;
|
||||
setupPin(pin: string): Promise<void>;
|
||||
removeAndDisablePin(): Promise<void>;
|
||||
showPinUnlockUI(): Promise<void>;
|
||||
showNativePinSetup(): Promise<void>;
|
||||
showPinUnlock(): Promise<void>;
|
||||
showPinSetup(): Promise<void>;
|
||||
}
|
||||
|
||||
export default TurboModuleRegistry.getEnforcing<Spec>('NativeVaultManager');
|
||||
|
||||
Reference in New Issue
Block a user