Add hasInternetCredentials (#150)
This checks if the username/password combination for server is available in the secure storage. Resolves to `true` if an entry exists or `false` if it doesn't.
This commit is contained in:
parent
1abc167b70
commit
b2c07b9f77
|
@ -61,6 +61,10 @@ Will remove the username/password combination from the secure storage.
|
||||||
|
|
||||||
Will store the server/username/password combination in the secure storage.
|
Will store the server/username/password combination in the secure storage.
|
||||||
|
|
||||||
|
### `hasInternetCredentials(server, [{ authenticationPrompt }])`
|
||||||
|
|
||||||
|
Will check if the username/password combination for server is available in the secure storage. Resolves to `true` if an entry exists or `false` if it doesn't.
|
||||||
|
|
||||||
### `getInternetCredentials(server, [{ authenticationPrompt }])`
|
### `getInternetCredentials(server, [{ authenticationPrompt }])`
|
||||||
|
|
||||||
Will retreive the server/username/password combination from the secure storage. Resolves to `{ username, password }` if an entry exists or `false` if it doesn't. It will reject only if an unexpected error is encountered like lacking entitlements or permission.
|
Will retreive the server/username/password combination from the secure storage. Resolves to `{ username, password }` if an entry exists or `false` if it doesn't. It will reject only if an unexpected error is encountered like lacking entitlements or permission.
|
||||||
|
|
|
@ -372,6 +372,35 @@ RCT_EXPORT_METHOD(setInternetCredentialsForServer:(NSString *)server withUsernam
|
||||||
[self insertKeychainEntry:attributes withOptions:options resolver:resolve rejecter:reject];
|
[self insertKeychainEntry:attributes withOptions:options resolver:resolve rejecter:reject];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(hasInternetCredentialsForServer:(NSString *)server resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
||||||
|
{
|
||||||
|
NSMutableDictionary *queryParts = [[NSMutableDictionary alloc] init];
|
||||||
|
queryParts[(__bridge NSString *)kSecClass] = (__bridge id)(kSecClassInternetPassword);
|
||||||
|
queryParts[(__bridge NSString *)kSecAttrServer] = server;
|
||||||
|
queryParts[(__bridge NSString *)kSecMatchLimit] = (__bridge NSString *)kSecMatchLimitOne;
|
||||||
|
|
||||||
|
if (@available(iOS 9, *)) {
|
||||||
|
queryParts[(__bridge NSString *)kSecUseAuthenticationUI] = (__bridge NSString *)kSecUseAuthenticationUIFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDictionary *query = [queryParts copy];
|
||||||
|
|
||||||
|
// Look up server in the keychain
|
||||||
|
OSStatus osStatus = SecItemCopyMatching((__bridge CFDictionaryRef) query, nil);
|
||||||
|
|
||||||
|
switch (osStatus) {
|
||||||
|
case noErr:
|
||||||
|
case errSecInteractionNotAllowed:
|
||||||
|
return resolve(@(YES));
|
||||||
|
|
||||||
|
case errSecItemNotFound:
|
||||||
|
return resolve(@(NO));
|
||||||
|
}
|
||||||
|
|
||||||
|
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
|
||||||
|
return rejectWithError(reject, error);
|
||||||
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(getInternetCredentialsForServer:(NSString *)server withOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
RCT_EXPORT_METHOD(getInternetCredentialsForServer:(NSString *)server withOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
||||||
{
|
{
|
||||||
NSDictionary *query = @{
|
NSDictionary *query = @{
|
||||||
|
|
|
@ -149,6 +149,19 @@ public class KeychainModule extends ReactContextBaseJavaModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void hasInternetCredentialsForServer(@NonNull String server, Promise promise) {
|
||||||
|
final String defaultService = getDefaultServiceIfNull(server);
|
||||||
|
|
||||||
|
ResultSet resultSet = prefsStorage.getEncryptedEntry(defaultService);
|
||||||
|
if (resultSet == null) {
|
||||||
|
Log.e(KEYCHAIN_MODULE, "No entry found for service: " + defaultService);
|
||||||
|
promise.resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void setInternetCredentialsForServer(@NonNull String server, String username, String password, ReadableMap unusedOptions, Promise promise) {
|
public void setInternetCredentialsForServer(@NonNull String server, String username, String password, ReadableMap unusedOptions, Promise promise) {
|
||||||
setGenericPasswordForOptions(server, username, password, promise);
|
setGenericPasswordForOptions(server, username, password, promise);
|
||||||
|
|
11
index.js
11
index.js
|
@ -108,6 +108,17 @@ export function setInternetCredentials(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if we have a login combination for `server`.
|
||||||
|
* @param {string} server URL to server.
|
||||||
|
* @return {Promise} Resolves to `true` when successful
|
||||||
|
*/
|
||||||
|
export function hasInternetCredentials(
|
||||||
|
server: string,
|
||||||
|
): Promise {
|
||||||
|
return RNKeychainManager.hasInternetCredentialsForServer(server);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches login combination for `server`.
|
* Fetches login combination for `server`.
|
||||||
* @param {string} server URL to server.
|
* @param {string} server URL to server.
|
||||||
|
|
|
@ -63,6 +63,10 @@ declare module 'react-native-keychain' {
|
||||||
server: string
|
server: string
|
||||||
): Promise<UserCredentials>;
|
): Promise<UserCredentials>;
|
||||||
|
|
||||||
|
function hasInternetCredentials(
|
||||||
|
server: string
|
||||||
|
): Promise<boolean>;
|
||||||
|
|
||||||
function resetInternetCredentials(
|
function resetInternetCredentials(
|
||||||
server: string
|
server: string
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
Loading…
Reference in New Issue