mCodex/react-native-sensitive-info

Occasional "PasswordVault The system cannot find the path specified." error when storing data

juhasuni opened this issue · 3 comments

The Windows implementation gives occasional errors with full error description of:

ERROR SAVE PasswordVault The system cannot find the path specified.

The error "The system cannot find the path specified" indicates that the PasswordVault file might be somehow missing or alternatively it is locked by another operation.

Both c++ and c# implementations initialize a new PasswordVault instance upon reading or writing data. My theory is, that upon writing data the PasswordVault file is locked and if you end up invoking two write operations simultaneously, you'll get the error.

Packages installed

"react-native-sensitive-info": "^6.0.0-alpha.9"
"react-native": "0.65.1"
"react-native-windows": "0.65.4"

It seems that we have solution for that issue.

We create one instance of const Windows::Security::Credentials::PasswordVault PasswordVault = Windows::Security::Credentials::PasswordVault(); PasswordVault object and use that same instance on all methods.

We will send PR later for this.

We patched current c++ implementation and this seems to work for us and no more PasswordVault error exists.

diff --git a/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.cpp b/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.cpp
index 5856cbf..5148b98 100644
--- a/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.cpp
+++ b/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.cpp
@@ -22,8 +22,7 @@ namespace winrt::RNSensitiveInfoCPP {
     }
     try {
       auto name = getSharedPreferences(options);
-      auto vault = PasswordVault();
-      auto data = vault.Retrieve(winrt::to_hstring(name), winrt::to_hstring(key));
+      auto data = PasswordVault.Retrieve(winrt::to_hstring(name), winrt::to_hstring(key));
       if (!data) {
         promise.Reject("key not found");
       } else {
@@ -44,11 +43,10 @@ namespace winrt::RNSensitiveInfoCPP {
     }
     try {
       auto name = getSharedPreferences(options);
-      auto vault = PasswordVault();
       PasswordCredential creds(winrt::to_hstring(name),
                                winrt::to_hstring(key),
                                winrt::to_hstring(value));
-      vault.Add(creds);
+      PasswordVault.Add(creds);
       promise.Resolve(value);
     } catch (...) {
       promise.Reject("cannot access datastore");
@@ -64,12 +62,11 @@ namespace winrt::RNSensitiveInfoCPP {
     }
     try {
       auto name = getSharedPreferences(options);
-      auto vault = PasswordVault();
-      auto data = vault.Retrieve(winrt::to_hstring(name), winrt::to_hstring(key));
+      auto data = PasswordVault.Retrieve(winrt::to_hstring(name), winrt::to_hstring(key));
       if (!data) {
         promise.Reject("key not found");
       } else {
-        vault.Remove(data);
+        PasswordVault.Remove(data);
         promise.Resolve(key);
       }
     } catch (...) {
@@ -81,11 +78,10 @@ namespace winrt::RNSensitiveInfoCPP {
                                     winrt::Microsoft::ReactNative::ReactPromise<winrt::Microsoft::ReactNative::JSValueObject> const& promise) noexcept {
     try {
       auto name = getSharedPreferences(options);
-      auto vault = PasswordVault();
-      auto allKeys = vault.FindAllByResource(winrt::to_hstring(name));
+      auto allKeys = PasswordVault.FindAllByResource(winrt::to_hstring(name));
       winrt::Microsoft::ReactNative::JSValueObject returnValue;
       for (auto const& key : allKeys) {
-        auto data = vault.Retrieve(winrt::to_hstring(name), key.UserName());
+        auto data = PasswordVault.Retrieve(winrt::to_hstring(name), key.UserName());
         returnValue[winrt::to_string(key.UserName())] = winrt::to_string(data.Password());
       }
       promise.Resolve(returnValue);
diff --git a/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.h b/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.h
index c9337fd..ad1c7d7 100644
--- a/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.h
+++ b/node_modules/react-native-sensitive-info/windows/code/RNSensitiveInfoCPP.h
@@ -15,6 +15,7 @@ namespace winrt::RNSensitiveInfoCPP {
   REACT_MODULE(RNSensitiveInfo);
   struct RNSensitiveInfo {
     const std::string Name = "RNSensitiveInfo";
+    const Windows::Security::Credentials::PasswordVault PasswordVault = Windows::Security::Credentials::PasswordVault();
     
     REACT_METHOD(getItem);
     void getItem(std::string key,
stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.