diff --git a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/nativevaultmanager/NativeVaultManager.kt b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/nativevaultmanager/NativeVaultManager.kt index bb8479c3f..191b3a27b 100644 --- a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/nativevaultmanager/NativeVaultManager.kt +++ b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/nativevaultmanager/NativeVaultManager.kt @@ -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) diff --git a/apps/mobile-app/app/(tabs)/settings/vault-unlock.tsx b/apps/mobile-app/app/(tabs)/settings/vault-unlock.tsx index 54983f8d1..94dfad3c6 100644 --- a/apps/mobile-app/app/(tabs)/settings/vault-unlock.tsx +++ b/apps/mobile-app/app/(tabs)/settings/vault-unlock.tsx @@ -162,7 +162,7 @@ export default function VaultUnlockSettingsScreen() : React.ReactNode { const handleEnablePin = useCallback(async () : Promise => { 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 { {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') })} {!hasBiometrics && ( diff --git a/apps/mobile-app/app/unlock.tsx b/apps/mobile-app/app/unlock.tsx index 1c5ad3e05..9906c0021 100644 --- a/apps/mobile-app/app/unlock.tsx +++ b/apps/mobile-app/app/unlock.tsx @@ -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 diff --git a/apps/mobile-app/i18n/locales/en.json b/apps/mobile-app/i18n/locales/en.json index 03089441e..e475c7e7e 100644 --- a/apps/mobile-app/i18n/locales/en.json +++ b/apps/mobile-app/i18n/locales/en.json @@ -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", diff --git a/apps/mobile-app/ios/NativeVaultManager/RCTNativeVaultManager.mm b/apps/mobile-app/ios/NativeVaultManager/RCTNativeVaultManager.mm index b4711e925..7e4122cc4 100644 --- a/apps/mobile-app/ios/NativeVaultManager/RCTNativeVaultManager.mm +++ b/apps/mobile-app/ios/NativeVaultManager/RCTNativeVaultManager.mm @@ -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 diff --git a/apps/mobile-app/ios/NativeVaultManager/VaultManager.swift b/apps/mobile-app/ios/NativeVaultManager/VaultManager.swift index c3f7bf689..579136f5e 100644 --- a/apps/mobile-app/ios/NativeVaultManager/VaultManager.swift +++ b/apps/mobile-app/ios/NativeVaultManager/VaultManager.swift @@ -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 { diff --git a/apps/mobile-app/ios/VaultUI/Auth/PinSetupView.swift b/apps/mobile-app/ios/VaultUI/Auth/PinSetupView.swift index 2795659cc..494215d79 100644 --- a/apps/mobile-app/ios/VaultUI/Auth/PinSetupView.swift +++ b/apps/mobile-app/ios/VaultUI/Auth/PinSetupView.swift @@ -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) diff --git a/apps/mobile-app/specs/NativeVaultManager.ts b/apps/mobile-app/specs/NativeVaultManager.ts index 8a355fcee..4ae8fe30f 100644 --- a/apps/mobile-app/specs/NativeVaultManager.ts +++ b/apps/mobile-app/specs/NativeVaultManager.ts @@ -92,12 +92,9 @@ export interface Spec extends TurboModule { // PIN unlock methods isPinEnabled(): Promise; - getPinLength(): Promise; - unlockWithPin(pin: string): Promise; - setupPin(pin: string): Promise; removeAndDisablePin(): Promise; - showPinUnlockUI(): Promise; - showNativePinSetup(): Promise; + showPinUnlock(): Promise; + showPinSetup(): Promise; } export default TurboModuleRegistry.getEnforcing('NativeVaultManager');