diff --git a/.editorconfig b/.editorconfig
index 5e19e7c0..b6dc064b 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -11,6 +11,7 @@ insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
+max_line_length = 100
[*.java]
diff --git a/.gitignore b/.gitignore
index 6e4eca2e..8a71fec8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,9 +62,8 @@ buck-out/
*.jsbundle
# CocoaPods
-/ios/Pods/
-/KeychainExample/ios/Pods/
-
+ios/Pods/
+KeychainExample/ios/Pods/
# Logs
*.log
diff --git a/KeychainExample/.gitignore b/KeychainExample/.gitignore
index 5d647565..f6888a53 100644
--- a/KeychainExample/.gitignore
+++ b/KeychainExample/.gitignore
@@ -21,6 +21,7 @@ DerivedData
*.ipa
*.xcuserstate
project.xcworkspace
+ios/Pods/
# Android/IntelliJ
#
diff --git a/KeychainExample/App.js b/KeychainExample/App.js
index 3b95c1e4..8442c1bd 100644
--- a/KeychainExample/App.js
+++ b/KeychainExample/App.js
@@ -109,6 +109,27 @@ export default class KeychainExample extends Component {
}
}
+ async ios_specifics() {
+ try {
+ const reply = await Keychain.setSharedWebCredentials(
+ 'server',
+ 'username',
+ 'password',
+ {}
+ );
+ console.log(`setSharedWebCredentials: ${JSON.stringify(reply)}`);
+ } catch (err) {
+ alert(`setSharedWebCredentials: ${err}`);
+ }
+
+ try {
+ const reply = await Keychain.requestSharedWebCredentials({});
+ console.log(`requestSharedWebCredentials: ${JSON.stringify(reply)}`)
+ } catch (err) {
+ alert(`requestSharedWebCredentials: ${err}`);
+ }
+ }
+
render() {
const VALUES =
Platform.OS === 'ios'
@@ -255,6 +276,19 @@ export default class KeychainExample extends Component {
)}
+
+ {Platform.OS === 'ios' && (
+
+ this.ios_specifics()}
+ style={styles.button}
+ >
+
+ Test Other APIs
+
+
+
+ )}
);
diff --git a/README.md b/README.md
index 397be3a5..0347f20f 100644
--- a/README.md
+++ b/README.md
@@ -8,31 +8,32 @@
[](https://travis-ci.org/oblador/react-native-keychain) [](https://npmjs.com/package/react-native-keychain) [](https://npmjs.com/package/react-native-keychain)
-# Keychain/Keystore Access for React Native.
+# Keychain/Keystore Access for React Native
-- [Keychain/Keystore Access for React Native.](#keychainkeystore-access-for-react-native)
+- [Keychain/Keystore Access for React Native](#keychainkeystore-access-for-react-native)
- [Installation](#installation)
- [Usage](#usage)
- [API](#api)
- - [`setGenericPassword(username, password, [{ accessControl, accessible, accessGroup, service, securityLevel }])`](#setgenericpasswordusername-password--accesscontrol-accessible-accessgroup-service-securitylevel)
- - [`getGenericPassword([{ authenticationPrompt, service }])`](#getgenericpassword-authenticationprompt-service)
- - [`resetGenericPassword([{ service }])`](#resetgenericpassword-service)
- - [`setInternetCredentials(server, username, password, [{ accessControl, accessible, accessGroup, securityLevel }])`](#setinternetcredentialsserver-username-password--accesscontrol-accessible-accessgroup-securitylevel)
- - [`hasInternetCredentials(server, [{ authenticationPrompt }])`](#hasinternetcredentialsserver--authenticationprompt)
- - [`getInternetCredentials(server, [{ authenticationPrompt }])`](#getinternetcredentialsserver--authenticationprompt)
- - [`resetInternetCredentials(server, [{}])`](#resetinternetcredentialsserver)
+ - [`setGenericPassword(username, password, [{ accessControl, accessible, accessGroup, service, securityLevel }])`](#setgenericpasswordusername-password--accesscontrol-accessible-accessgroup-service-securitylevel-)
+ - [`getGenericPassword([{ authenticationPrompt, service }])`](#getgenericpassword-authenticationprompt-service-)
+ - [`resetGenericPassword([{ service }])`](#resetgenericpassword-service-)
+ - [`setInternetCredentials(server, username, password, [{ accessControl, accessible, accessGroup, securityLevel }])`](#setinternetcredentialsserver-username-password--accesscontrol-accessible-accessgroup-securitylevel-)
+ - [`hasInternetCredentials(server, [{ authenticationPrompt }])`](#hasinternetcredentialsserver--authenticationprompt-)
+ - [`getInternetCredentials(server, [{ authenticationPrompt }])`](#getinternetcredentialsserver--authenticationprompt-)
+ - [`resetInternetCredentials(server, [{}])`](#resetinternetcredentialsserver-)
- [`requestSharedWebCredentials()` (iOS only)](#requestsharedwebcredentials-ios-only)
- [`setSharedWebCredentials(server, username, password)` (iOS only)](#setsharedwebcredentialsserver-username-password-ios-only)
- [`canImplyAuthentication([{ authenticationType }])` (iOS only)](#canimplyauthentication-authenticationtype--ios-only)
- [`getSupportedBiometryType([{}])`](#getsupportedbiometrytype)
- - [`getSecurityLevel([{}])` (Android only)](#getsecuritylevel-android-only)
+ - [`getSecurityLevel([{ accessControl }])` (Android only)](#getsecuritylevel-accesscontrol--android-only)
- [Options](#options)
- - [`Keychain.ACCESS_CONTROL` enum](#keychainaccesscontrol-enum)
+ - [Data Structure Properties/Fields](#data-structure-propertiesfields)
+ - [`Keychain.ACCESS_CONTROL` enum](#keychainaccess_control-enum)
- [`Keychain.ACCESSIBLE` enum](#keychainaccessible-enum)
- - [`Keychain.AUTHENTICATION_TYPE` enum](#keychainauthenticationtype-enum)
- - [`Keychain.BIOMETRY_TYPE` enum](#keychainbiometrytype-enum)
- - [`Keychain.SECURITY_LEVEL` enum (Android only)](#keychainsecuritylevel-enum-android-only)
- - [`Keychain.STORAGE_TYPE` enum (Android only)](#keychainstoragetype-enum-android-only)
+ - [`Keychain.AUTHENTICATION_TYPE` enum](#keychainauthentication_type-enum)
+ - [`Keychain.BIOMETRY_TYPE` enum](#keychainbiometry_type-enum)
+ - [`Keychain.SECURITY_LEVEL` enum (Android only)](#keychainsecurity_level-enum-android-only)
+ - [`Keychain.STORAGE_TYPE` enum (Android only)](#keychainstorage_type-enum-android-only)
- [`Keychain.RULES` enum (Android only)](#keychainrules-enum-android-only)
- [Important Behavior](#important-behavior)
- [Rule 1: Automatic Security Level Upgrade](#rule-1-automatic-security-level-upgrade)
@@ -108,11 +109,11 @@ Will retrieve the username/password combination from the secure storage. Resolve
### `resetGenericPassword([{ service }])`
-Will remove the username/password combination from the secure storage. Returns `true` in case of success.
+Will remove the username/password combination from the secure storage. Resolves to `true` in case of success.
### `setInternetCredentials(server, username, password, [{ accessControl, accessible, accessGroup, securityLevel }])`
-Will store the server/username/password combination in the secure storage. Returns `{ username, password, service, storage }`;
+Will store the server/username/password combination in the secure storage. Resolves to `{ username, password, service, storage }`;
### `hasInternetCredentials(server, [{ authenticationPrompt }])`
@@ -124,7 +125,7 @@ Will retrieve the server/username/password combination from the secure storage.
### `resetInternetCredentials(server, [{}])`
-Will remove the server/username/password combination from the secure storage.
+Will remove the server/username/password combination from the secure storage. Method accept `options` object instance but ignores all it values for now. Its reserved for future functionality.
### `requestSharedWebCredentials()` (iOS only)
@@ -140,16 +141,18 @@ Inquire if the type of local authentication policy is supported on this device w
### `getSupportedBiometryType([{}])`
-Get what type of hardware biometry support the device has. Resolves to a `Keychain.BIOMETRY_TYPE` value when supported, otherwise `null`.
+Get what type of hardware biometry support the device has. Resolves to a `Keychain.BIOMETRY_TYPE` value when supported, otherwise `null`. Method accept `options` object instance but ignores all it values for now. Its reserved for future functionality.
> This method returns `null`, if the device haven't enrolled into fingerprint/FaceId. Even though it has hardware for it.
-### `getSecurityLevel([{}])` (Android only)
+### `getSecurityLevel([{ accessControl }])` (Android only)
-Get security level that is supported on the current device with the current OS.
+Get security level that is supported on the current device with the current OS. Resolves to `Keychain.SECURITY_LEVEL` enum value.
### Options
+#### Data Structure Properties/Fields
+
| Key | Platform | Description | Default |
| -------------------------- | ------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ |
| **`accessControl`** | All | This dictates how a keychain item may be used, see possible values in `Keychain.ACCESS_CONTROL`. | *None* (iOS), `BIOMETRY_ANY` default for Android. |
diff --git a/RNKeychainManager/RNKeychainManager.m b/RNKeychainManager/RNKeychainManager.m
index c4ad7e59..e6a1a131 100644
--- a/RNKeychainManager/RNKeychainManager.m
+++ b/RNKeychainManager/RNKeychainManager.m
@@ -174,7 +174,10 @@ SecAccessControlCreateFlags accessControlValue(NSDictionary *options)
return 0;
}
-- (void)insertKeychainEntry:(NSDictionary *)attributes withOptions:(NSDictionary * __nullable)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject
+- (void)insertKeychainEntry:(NSDictionary *)attributes
+ withOptions:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject
{
NSString *accessGroup = accessGroupValue(options);
CFStringRef accessible = accessibleValue(options);
@@ -217,7 +220,11 @@ - (void)insertKeychainEntry:(NSDictionary *)attributes withOptions:(NSDictionary
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
return rejectWithError(reject, error);
} else {
- return resolve(@(YES));
+ NSString *service = serviceValue(options);
+ return resolve(@{
+ @"server": service,
+ @"storage": @"keychain"
+ });
}
});
});
@@ -250,7 +257,9 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
#pragma mark - RNKeychain
#if TARGET_OS_IOS
-RCT_EXPORT_METHOD(canCheckAuthentication:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(canCheckAuthentication:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
LAPolicy policyToEvaluate = authPolicy(options);
@@ -266,7 +275,8 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
#endif
#if TARGET_OS_IOS
-RCT_EXPORT_METHOD(getSupportedBiometryType:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(getSupportedBiometryType:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
NSError *aerr = nil;
LAContext *context = [LAContext new];
@@ -285,9 +295,14 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
}
#endif
-RCT_EXPORT_METHOD(setGenericPasswordForOptions:(NSDictionary *)options withUsername:(NSString *)username withPassword:(NSString *)password withSecurityLevel:(__unused NSString *)level resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(setGenericPasswordForOptions:(NSString *)service
+ withUsername:(NSString *)username
+ withPassword:(NSString *)password
+ withOptions:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
- NSString *service = serviceValue(options);
+ if(service == NULL) service = serviceValue(options);
NSDictionary *attributes = attributes = @{
(__bridge NSString *)kSecClass: (__bridge id)(kSecClassGenericPassword),
(__bridge NSString *)kSecAttrService: service,
@@ -300,9 +315,12 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
[self insertKeychainEntry:attributes withOptions:options resolver:resolve rejecter:reject];
}
-RCT_EXPORT_METHOD(getGenericPasswordForOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(getGenericPasswordForOptions:(NSString *)service
+ withOptions:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
- NSString *service = serviceValue(options);
+ if(service == NULL) service = serviceValue(options);
NSString *authenticationPrompt = @"Authenticate to retrieve secret";
if (options && options[kAuthenticationPromptMessage]) {
authenticationPrompt = options[kAuthenticationPromptMessage];
@@ -340,12 +358,15 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
return resolve(@{
@"service": service,
@"username": username,
- @"password": password
+ @"password": password,
+ @"storage": @"keychain"
});
}
-RCT_EXPORT_METHOD(resetGenericPasswordForOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(resetGenericPasswordForOptions:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
NSString *service = serviceValue(options);
@@ -359,7 +380,12 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
return resolve(@(YES));
}
-RCT_EXPORT_METHOD(setInternetCredentialsForServer:(NSString *)server withUsername:(NSString*)username withPassword:(NSString*)password withSecurityLevel:(__unused NSString *)level withOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(setInternetCredentialsForServer:(NSString *)server
+ withUsername:(NSString*)username
+ withPassword:(NSString*)password
+ withOptions:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
[self deleteCredentialsForServer:server];
@@ -373,7 +399,9 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
[self insertKeychainEntry:attributes withOptions:options resolver:resolve rejecter:reject];
}
-RCT_EXPORT_METHOD(hasInternetCredentialsForServer:(NSString *)server resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)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);
@@ -402,7 +430,10 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
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 * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
NSDictionary *query = @{
(__bridge NSString *)kSecClass: (__bridge id)(kSecClassInternetPassword),
@@ -435,12 +466,16 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
return resolve(@{
@"server": server,
@"username": username,
- @"password": password
+ @"password": password,
+ @"storage": @"keychain"
});
}
-RCT_EXPORT_METHOD(resetInternetCredentialsForServer:(NSString *)server withOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(resetInternetCredentialsForServer:(NSString *)server
+ withOptions:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
OSStatus osStatus = [self deleteCredentialsForServer:server];
@@ -453,8 +488,11 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
}
#if TARGET_OS_IOS && !TARGET_OS_UIKITFORMAC
-RCT_EXPORT_METHOD(requestSharedWebCredentials:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(requestSharedWebCredentials:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
+ /* Options can be used for specifying the [domain & account == server & username] */
SecRequestSharedWebCredential(NULL, NULL, ^(CFArrayRef credentials, CFErrorRef error) {
if (error != NULL) {
NSError *nsError = (__bridge NSError *)error;
@@ -470,7 +508,8 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
return resolve(@{
@"server": server,
@"username": username,
- @"password": password
+ @"password": password,
+ @"storage": @"keychain"
});
}
return resolve(@(NO));
@@ -478,7 +517,12 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server
}
-RCT_EXPORT_METHOD(setSharedWebCredentialsForServer:(NSString *)server withUsername:(NSString *)username withPassword:(NSString *)password resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+RCT_EXPORT_METHOD(setSharedWebCredentialsForServer:(NSString *)server
+ withUsername:(NSString *)username
+ withPassword:(NSString *)password
+ withOptions:(NSDictionary * __nullable)options
+ resolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
{
SecAddSharedWebCredential(
(__bridge CFStringRef)server,
diff --git a/android/README.md b/android/README.md
index e7b04c66..267b8307 100644
--- a/android/README.md
+++ b/android/README.md
@@ -33,6 +33,11 @@
react-native start --reset-cache
```
+```bash
+# set working dir to: 'react-native-keychain/KeychainExample'
+/usr/bin/env node node_modules/.bin/react-native start --reset-cache
+```
+
> Important! to set checkbox `Allow parallel run`.
### Create Automatic self-refreshed TCP ports binding
diff --git a/android/build.gradle b/android/build.gradle
index 3af89e3f..46b074ef 100755
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -25,22 +25,17 @@ android {
targetSdkVersion safeExtGet('targetSdkVersion', 28)
versionCode 1
versionName "1.0"
-
-// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
+
lintOptions {
abortOnError false
}
+
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
- // Gradle automatically adds 'android.test.runner' as a dependency.
-// useLibrary 'android.test.runner'
-// useLibrary 'android.test.base'
-// useLibrary 'android.test.mock'
-
testOptions {
unitTests {
includeAndroidResources = true
@@ -89,13 +84,3 @@ dependencies {
// Uncomment for including JRE implementation of crypto api (that is used in Robolectric tests)
// testImplementation fileTree(dir: "${System.properties.get("java.home")}/lib", include: ["jce.jar"])
}
-//
-//task updateLibrarySourceInExample(type: Copy) {
-// from "${project.projectDir}/src/"
-// // react-native-keychain/KeychainExample/node_modules/react-native-keychain/android/src
-// into "${rootProject.projectDir}/KeychainExample/node_modules/react-native-keychain/android/src"
-//}
-//
-//gradle.projectsEvaluated {
-// preBuild.dependsOn(updateLibrarySourceInExample)
-//}
diff --git a/android/src/main/java/com/oblador/keychain/PrefsStorage.java b/android/src/main/java/com/oblador/keychain/PrefsStorage.java
index d653b085..e5768c9b 100644
--- a/android/src/main/java/com/oblador/keychain/PrefsStorage.java
+++ b/android/src/main/java/com/oblador/keychain/PrefsStorage.java
@@ -75,7 +75,7 @@ public void storeEncryptedEntry(@NonNull final String service, @NonNull final En
prefs.edit()
.putString(keyForUsername, Base64.encodeToString(encryptionResult.username, Base64.DEFAULT))
.putString(keyForPassword, Base64.encodeToString(encryptionResult.password, Base64.DEFAULT))
- .putString(keyForCipherStorage, encryptionResult.cipherStorage.getCipherStorageName())
+ .putString(keyForCipherStorage, encryptionResult.cipherName)
.apply();
}
diff --git a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorage.java b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorage.java
index eaeacd23..cce079ae 100644
--- a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorage.java
+++ b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorage.java
@@ -18,7 +18,7 @@ abstract class CipherResult {
public final T username;
public final T password;
- public CipherResult(T username, T password) {
+ public CipherResult(final T username, final T password) {
this.username = username;
this.password = password;
}
@@ -26,11 +26,18 @@ public CipherResult(T username, T password) {
/** Credentials in bytes array, often a result of encryption. */
class EncryptionResult extends CipherResult {
- public final CipherStorage cipherStorage;
+ /** Name of used for encryption cipher storage. */
+ public final String cipherName;
- public EncryptionResult(final byte[] username, final byte[] password, final CipherStorage cipherStorage) {
+ /** Main constructor. */
+ public EncryptionResult(final byte[] username, final byte[] password, final String cipherName) {
super(username, password);
- this.cipherStorage = cipherStorage;
+ this.cipherName = cipherName;
+ }
+
+ /** Helper constructor. Simplifies cipher name extraction. */
+ public EncryptionResult(final byte[] username, final byte[] password, @NonNull final CipherStorage cipherStorage) {
+ this(username, password, cipherStorage.getCipherStorageName());
}
}
diff --git a/index.js b/index.js
index a4d2e40b..a6856f53 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,7 @@
// @flow
-import { NativeModules, Platform } from 'react-native';
-const { RNKeychainManager } = NativeModules;
+import {NativeModules, Platform} from 'react-native';
+
+const {RNKeychainManager} = NativeModules;
export const SECURITY_LEVEL = Object.freeze({
ANY: RNKeychainManager.SECURITY_LEVEL_ANY,
@@ -44,6 +45,7 @@ export const STORAGE_TYPE = Object.freeze({
FB: 'FacebookConceal',
AES: 'KeystoreAESCBC',
RSA: 'KeystoreRSAECB',
+ KC: 'keychain', // <~ iOS only
});
export const SECURITY_RULES = Object.freeze({
@@ -63,6 +65,8 @@ export type SecStorageType = $Values;
export type SecSecurityRules = $Values;
+export type SecBiometryType = $Values;
+
export type Options = {
accessControl?: SecAccessControl,
accessGroup?: string,
@@ -91,68 +95,39 @@ export type SharedWebCredentials = {|
...UserCredentials,
|};
-function getOptionsArgument(serviceOrOptions?: string | Options) {
- if (Platform.OS !== 'ios') {
- return typeof serviceOrOptions === 'object'
- ? serviceOrOptions.service
- : serviceOrOptions;
- }
- return typeof serviceOrOptions === 'string'
- ? { service: serviceOrOptions }
- : serviceOrOptions;
-}
-
-function getAccessControl(serviceOrOptions?: string | Options) {
- var accessControl = null;
-
- if (typeof serviceOrOptions === 'object') {
- accessControl = serviceOrOptions.accessControl;
- }
-
- return accessControl;
-}
-
-function getMinimumSecurityLevel(serviceOrOptions?: string | Options) {
- var specifiedLevel = undefined;
-
- if (typeof serviceOrOptions === 'object') {
- specifiedLevel = serviceOrOptions.securityLevel;
- }
-
- return specifiedLevel || SECURITY_LEVEL.ANY;
-}
+//* EXPORTS */
/**
* Saves the `username` and `password` combination for `service`.
* @param {string} username Associated username or e-mail to be saved.
* @param {string} password Associated password to be saved.
- * @param {object} options An Keychain options object.
+ * @param {object} options A keychain options object.
* @return {Promise} Resolves to `{ service, storage }` when successful
*/
export function setGenericPassword(
username: string,
password: string,
- options?: Options
+ options?: Options,
): Promise {
- var obj: { service?: string } = options || {};
+ const obj: { service?: string } = options || {};
return RNKeychainManager.setGenericPasswordForOptions(
obj.service,
username,
password,
- options
+ options,
);
}
/**
* Fetches login combination for `service`.
- * @param {object} options An Keychain options object.
+ * @param {object} options A keychain options object.
* @return {Promise} Resolves to `{ service, username, password, storage }` when successful
*/
export function getGenericPassword(
- options?: Options
+ options?: Options,
): Promise {
- var obj: { service?: string } = options || {};
+ const obj: { service?: string } = options || {};
return RNKeychainManager.getGenericPasswordForOptions(obj.service, options);
}
@@ -163,7 +138,7 @@ export function getGenericPassword(
* @return {Promise} Resolves to `true` when successful
*/
export function resetGenericPassword(options?: Options): Promise {
- var obj: { service?: string } = options || {};
+ const obj: { service?: string } = options || {};
return RNKeychainManager.resetGenericPasswordForOptions(obj.service, options);
}
@@ -176,7 +151,7 @@ export function resetGenericPassword(options?: Options): Promise {
*/
export function hasInternetCredentials(
server: string,
- options?: Options
+ options?: Options,
): Promise {
return RNKeychainManager.hasInternetCredentialsForServer(server, options);
}
@@ -193,13 +168,13 @@ export function setInternetCredentials(
server: string,
username: string,
password: string,
- options?: Options
+ options?: Options,
): Promise {
return RNKeychainManager.setInternetCredentialsForServer(
server,
username,
password,
- options
+ options,
);
}
@@ -211,7 +186,7 @@ export function setInternetCredentials(
*/
export function getInternetCredentials(
server: string,
- options?: Options
+ options?: Options,
): Promise {
return RNKeychainManager.getInternetCredentialsForServer(server, options);
}
@@ -224,12 +199,31 @@ export function getInternetCredentials(
*/
export function resetInternetCredentials(
server: string,
- options?: Options
+ options?: Options,
): Promise {
return RNKeychainManager.resetInternetCredentialsForServer(server, options);
}
-/** IOS ONLY */
+/**
+ * Get what type of hardware biometry support the device has.
+ * @param {object} options An Keychain options object.
+ * @return {Promise} Resolves to a `BIOMETRY_TYPE` when supported, otherwise `null`
+ */
+export function getSupportedBiometryType(
+ options?: Options,
+): Promise {
+ if (!RNKeychainManager.getSupportedBiometryType) {
+ return Promise.resolve(null);
+ }
+
+ if (Platform.OS === 'ios') {
+ return RNKeychainManager.getSupportedBiometryType();
+ }
+
+ return RNKeychainManager.getSupportedBiometryType(options);
+}
+
+//* IOS ONLY */
/**
* Asks the user for a shared web credential.
@@ -237,13 +231,13 @@ export function resetInternetCredentials(
* `false` if denied and throws an error if not supported on platform or there's no shared credentials
*/
export function requestSharedWebCredentials(
- options: ?Options
+ options?: Options,
): Promise {
if (Platform.OS !== 'ios') {
return Promise.reject(
new Error(
- `requestSharedWebCredentials() is not supported on ${Platform.OS} yet`
- )
+ `requestSharedWebCredentials() is not supported on ${Platform.OS} yet`,
+ ),
);
}
return RNKeychainManager.requestSharedWebCredentials(options);
@@ -254,27 +248,27 @@ export function requestSharedWebCredentials(
* @param {string} server URL to server.
* @param {string} username Associated username or e-mail to be saved.
* @param {string} password Associated password to be saved.
- * @param {object} options An Keychain options object.
+ * @param {object} options a keychain options object.
* @return {Promise} Resolves to `true` when successful
*/
export function setSharedWebCredentials(
server: string,
username: string,
- password: ?string,
- options: ?Options
+ password?: string,
+ options?: Options,
): Promise {
if (Platform.OS !== 'ios') {
return Promise.reject(
new Error(
- `setSharedWebCredentials() is not supported on ${Platform.OS} yet`
- )
+ `setSharedWebCredentials() is not supported on ${Platform.OS} yet`,
+ ),
);
}
return RNKeychainManager.setSharedWebCredentialsForServer(
server,
username,
password,
- options
+ options,
);
}
@@ -291,7 +285,7 @@ export function canImplyAuthentication(options?: Options): Promise {
return RNKeychainManager.canCheckAuthentication(options);
}
-/** ANDROID ONLY */
+//* ANDROID ONLY */
/**
* (Android only) Returns guaranteed security level supported by this library
@@ -300,47 +294,33 @@ export function canImplyAuthentication(options?: Options): Promise {
* @return {Promise} Resolves to `SECURITY_LEVEL` when supported, otherwise `null`.
*/
export function getSecurityLevel(
- options?: Options
-): Promise$Values> {
+ options?: Options,
+): Promise {
if (!RNKeychainManager.getSecurityLevel) {
return Promise.resolve(null);
}
return RNKeychainManager.getSecurityLevel(options);
}
-/**
- * Get what type of hardware biometry support the device has.
- * @param {object} options An Keychain options object.
- * @return {Promise} Resolves to a `BIOMETRY_TYPE` when supported, otherwise `null`
- */
-export function getSupportedBiometryType(
- options?: Options
-): Promise$Values> {
- if (!RNKeychainManager.getSupportedBiometryType) {
- return Promise.resolve(null);
- }
- return RNKeychainManager.getSupportedBiometryType(options);
-}
-
/** Refs: https://www.saltycrane.com/cheat-sheets/flow-type/latest/ */
export default {
- SECURITY_LEVEL,
- ACCESSIBLE,
- ACCESS_CONTROL,
- AUTHENTICATION_TYPE,
- BIOMETRY_TYPE,
- getSecurityLevel,
- canImplyAuthentication,
- getSupportedBiometryType,
- setInternetCredentials,
- getInternetCredentials,
- resetInternetCredentials,
- getOptionsArgument,
- getMinimumSecurityLevel,
- setGenericPassword,
- getGenericPassword,
- resetGenericPassword,
- requestSharedWebCredentials,
- setSharedWebCredentials
-}
+ SECURITY_LEVEL,
+ ACCESSIBLE,
+ ACCESS_CONTROL,
+ AUTHENTICATION_TYPE,
+ BIOMETRY_TYPE,
+ STORAGE_TYPE,
+ SECURITY_RULES,
+ getSecurityLevel,
+ canImplyAuthentication,
+ getSupportedBiometryType,
+ setInternetCredentials,
+ getInternetCredentials,
+ resetInternetCredentials,
+ setGenericPassword,
+ getGenericPassword,
+ resetGenericPassword,
+ requestSharedWebCredentials,
+ setSharedWebCredentials,
+};
diff --git a/typings/react-native-keychain.d.ts b/typings/react-native-keychain.d.ts
index b9c52c80..8f19dbf2 100644
--- a/typings/react-native-keychain.d.ts
+++ b/typings/react-native-keychain.d.ts
@@ -54,6 +54,7 @@ declare module 'react-native-keychain' {
FB = 'FacebookConceal',
AES = 'KeystoreAESCBC',
RSA = 'KeystoreRSAECB',
+ KC = 'keychain',
}
export enum SECURITY_RULES {
@@ -109,7 +110,7 @@ declare module 'react-native-keychain' {
function getSupportedBiometryType(
options?: Options
- ): Promise;
+ ): Promise;
/** IOS ONLY */
@@ -128,5 +129,5 @@ declare module 'react-native-keychain' {
/** ANDROID ONLY */
- function getSecurityLevel(options?: Options): Promise;
+ function getSecurityLevel(options?: Options): Promise;
}