|
21 | 21 | namespace auth {
|
22 | 22 | namespace secure {
|
23 | 23 |
|
| 24 | +// Prefix and suffix to add to keychain service name. |
24 | 25 | static const char kServicePrefix[] = "";
|
25 | 26 | static const char kServiceSuffix[] = " [Firebase Auth]";
|
26 | 27 | static const int kMaxAllowedKeychainEntries = INT_MAX;
|
27 | 28 |
|
| 29 | +// Prefix and suffix for the key for NSUserDefaults. |
| 30 | +static const char kUserDefaultsPrefix[] = "com.google.firebase.auth."; |
| 31 | +static const char kUserDefaultsSuffix[] = ".has_saved_user"; |
| 32 | + |
28 | 33 | UserSecureDarwinInternal::UserSecureDarwinInternal(const char* service) {
|
29 | 34 | service_ = std::string(kServicePrefix) + service + std::string(kServiceSuffix);
|
| 35 | + user_defaults_key_ = |
| 36 | + std::string(kUserDefaultsPrefix) + service + std::string(kUserDefaultsSuffix); |
30 | 37 | }
|
31 | 38 |
|
32 | 39 | UserSecureDarwinInternal::~UserSecureDarwinInternal() {}
|
|
47 | 54 | return service_ + "/" + app;
|
48 | 55 | }
|
49 | 56 |
|
| 57 | +bool UserSecureDarwinInternal::UserHasSecureData() { |
| 58 | + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
| 59 | + if (!defaults) { |
| 60 | + // For some reason we can't get NSUserDefaults, so just err on the safe side and return true so |
| 61 | + // we check the keychain directly. |
| 62 | + return true; |
| 63 | + } |
| 64 | + return [defaults boolForKey:@(user_defaults_key_.c_str())] ? true : false; |
| 65 | +} |
| 66 | + |
| 67 | +void UserSecureDarwinInternal::SetUserHasSecureData(bool b) { |
| 68 | + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
| 69 | + [defaults setBool:(b ? YES : NO) forKey:@(user_defaults_key_.c_str())]; |
| 70 | + [defaults synchronize]; |
| 71 | +} |
| 72 | + |
50 | 73 | std::string UserSecureDarwinInternal::LoadUserData(const std::string& app_name) {
|
| 74 | + if (!UserHasSecureData()) { |
| 75 | + LogDebug("LoadUserData: User has no data stored."); |
| 76 | + return ""; |
| 77 | + } |
51 | 78 | NSMutableDictionary* query = GetQueryForApp(service_.c_str(), app_name.c_str());
|
52 | 79 | std::string keystore_location = GetKeystoreLocation(app_name);
|
53 | 80 | // We want to return the data and attributes.
|
|
111 | 138 | error_string.UTF8String);
|
112 | 139 | return;
|
113 | 140 | }
|
| 141 | + |
| 142 | + SetUserHasSecureData(true); |
114 | 143 | }
|
115 | 144 |
|
116 | 145 | void UserSecureDarwinInternal::DeleteData(const char* app_name, const char* func_name) {
|
| 146 | + if (!UserHasSecureData()) { |
| 147 | + LogDebug("%s: User has no data stored.", func_name); |
| 148 | + return; |
| 149 | + } |
| 150 | + |
117 | 151 | NSMutableDictionary* query = GetQueryForApp(service_.c_str(), app_name);
|
118 | 152 | std::string keystore_location = app_name ? GetKeystoreLocation(app_name) : service_;
|
119 | 153 |
|
|
125 | 159 | OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);
|
126 | 160 |
|
127 | 161 | if (status == errSecItemNotFound) {
|
128 |
| - LogDebug("%s: Key %s not found", keystore_location.c_str()); |
| 162 | + LogDebug("%s: Key %s not found", func_name, keystore_location.c_str()); |
129 | 163 | return;
|
130 | 164 | } else if (status != noErr) {
|
131 | 165 | NSString* error_string = (__bridge_transfer NSString*)SecCopyErrorMessageString(status, NULL);
|
132 |
| - LogError("%s: Error %d deleting %s: %s", status, keystore_location.c_str(), |
| 166 | + LogError("%s: Error %d deleting %s: %s", func_name, status, keystore_location.c_str(), |
133 | 167 | error_string.UTF8String);
|
134 | 168 | return;
|
135 | 169 | }
|
|
139 | 173 | DeleteData(app_name.c_str(), "DeleteUserData");
|
140 | 174 | }
|
141 | 175 |
|
142 |
| -void UserSecureDarwinInternal::DeleteAllData() { DeleteData(nullptr, "DeleteAllData"); } |
| 176 | +void UserSecureDarwinInternal::DeleteAllData() { |
| 177 | + DeleteData(nullptr, "DeleteAllData"); |
| 178 | + SetUserHasSecureData(false); |
| 179 | +} |
143 | 180 |
|
144 | 181 | } // namespace secure
|
145 | 182 | } // namespace auth
|
|
0 commit comments