274 lines
8.5 KiB
JavaScript
Raw Normal View History

// @flow
2016-11-04 11:42:12 +01:00
import { NativeModules, Platform } from 'react-native';
const { RNKeychainManager } = NativeModules;
2015-05-20 18:23:04 +02:00
export const SECURITY_LEVEL = Object.freeze({
2019-01-20 21:24:48 +01:00
ANY: RNKeychainManager.SECURITY_LEVEL_ANY,
SECURE_SOFTWARE: RNKeychainManager.SECURITY_LEVEL_SECURE_SOFTWARE,
SECURE_HARDWARE: RNKeychainManager.SECURITY_LEVEL_SECURE_HARDWARE,
});
export const ACCESSIBLE = Object.freeze({
2018-02-25 17:29:39 +01:00
WHEN_UNLOCKED: 'AccessibleWhenUnlocked',
AFTER_FIRST_UNLOCK: 'AccessibleAfterFirstUnlock',
ALWAYS: 'AccessibleAlways',
WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: 'AccessibleWhenPasscodeSetThisDeviceOnly',
WHEN_UNLOCKED_THIS_DEVICE_ONLY: 'AccessibleWhenUnlockedThisDeviceOnly',
AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY:
'AccessibleAfterFirstUnlockThisDeviceOnly',
ALWAYS_THIS_DEVICE_ONLY: 'AccessibleAlwaysThisDeviceOnly',
});
2018-02-25 17:29:39 +01:00
export const ACCESS_CONTROL = Object.freeze({
2018-02-25 17:29:39 +01:00
USER_PRESENCE: 'UserPresence',
2018-02-26 00:14:48 +01:00
BIOMETRY_ANY: 'BiometryAny',
BIOMETRY_CURRENT_SET: 'BiometryCurrentSet',
2018-02-25 17:29:39 +01:00
DEVICE_PASSCODE: 'DevicePasscode',
APPLICATION_PASSWORD: 'ApplicationPassword',
2018-02-26 00:14:48 +01:00
BIOMETRY_ANY_OR_DEVICE_PASSCODE: 'BiometryAnyOrDevicePasscode',
BIOMETRY_CURRENT_SET_OR_DEVICE_PASSCODE: 'BiometryCurrentSetOrDevicePasscode',
});
2018-02-25 17:29:39 +01:00
export const AUTHENTICATION_TYPE = Object.freeze({
2018-02-25 17:29:39 +01:00
DEVICE_PASSCODE_OR_BIOMETRICS: 'AuthenticationWithBiometricsDevicePasscode',
BIOMETRICS: 'AuthenticationWithBiometrics',
});
2018-02-25 17:29:39 +01:00
export const BIOMETRY_TYPE = Object.freeze({
2018-02-25 17:05:33 +01:00
TOUCH_ID: 'TouchID',
FACE_ID: 'FaceID',
FINGERPRINT: 'Fingerprint',
});
export type SecAccessible = $Values<typeof ACCESSIBLE>;
2018-02-25 17:05:33 +01:00
export type SecAccessControl = $Values<typeof ACCESS_CONTROL>;
export type LAPolicy = $Values<typeof AUTHENTICATION_TYPE>;
export type SecMinimumLevel = $Values<typeof SECURITY_LEVEL>;
export type Options = {
accessControl?: SecAccessControl,
accessGroup?: string,
accessible?: SecAccessible,
authenticationPrompt?: string,
authenticationType?: LAPolicy,
service?: string,
securityLevel?: SecMinimumLevel,
};
/**
* (Android only) Returns guaranteed security level supported by this library
* on the current device.
* @return {Promise} Resolves to `SECURITY_LEVEL` when supported, otherwise `null`.
*/
2019-01-20 21:24:48 +01:00
export function getSecurityLevel(): Promise<?($Values<typeof SECURITY_LEVEL>)> {
if (!RNKeychainManager.getSecurityLevel){
return Promise.resolve(null);
}
return RNKeychainManager.getSecurityLevel();
}
/**
* Inquire if the type of local authentication policy (LAPolicy) is supported
* on this device with the device settings the user chose.
* @param {object} options LAPolicy option, iOS only
2018-02-25 17:07:18 +01:00
* @return {Promise} Resolves to `true` when supported, otherwise `false`
*/
export function canImplyAuthentication(options?: Options): Promise<boolean> {
if (!RNKeychainManager.canCheckAuthentication) {
return Promise.resolve(false);
}
return RNKeychainManager.canCheckAuthentication(options);
}
2018-02-25 17:05:33 +01:00
/**
2018-02-27 13:58:37 +01:00
* Get what type of hardware biometry support the device has.
2018-02-25 17:05:33 +01:00
* @return {Promise} Resolves to a `BIOMETRY_TYPE` when supported, otherwise `null`
*/
export function getSupportedBiometryType(): Promise<?($Values<typeof BIOMETRY_TYPE>)> {
2018-02-25 20:21:01 +01:00
if (!RNKeychainManager.getSupportedBiometryType) {
return Promise.resolve(null);
2018-02-25 17:05:33 +01:00
}
return RNKeychainManager.getSupportedBiometryType();
}
2016-11-04 11:42:12 +01:00
/**
* Saves the `username` and `password` combination for `server`.
* @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 Keychain options, iOS only
* @return {Promise} Resolves to `true` when successful
2016-11-04 11:42:12 +01:00
*/
export function setInternetCredentials(
server: string,
username: string,
password: string,
options?: Options
): Promise<void> {
return RNKeychainManager.setInternetCredentialsForServer(
server,
username,
password,
getMinimumSecurityLevel(options),
options
);
2016-11-04 11:42:12 +01:00
}
2015-05-20 20:39:52 +02:00
/**
* 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<boolean> {
return RNKeychainManager.hasInternetCredentialsForServer(server);
}
export type UserCredentials = {|
+username: string,
+password: string,
|};
2016-11-04 11:42:12 +01:00
/**
* Fetches login combination for `server`.
* @param {string} server URL to server.
* @param {object} options Keychain options, iOS only
* @return {Promise} Resolves to `{ server, username, password }` when successful
2016-11-04 11:42:12 +01:00
*/
export function getInternetCredentials(
server: string,
options?: Options
): Promise<UserCredentials> {
return RNKeychainManager.getInternetCredentialsForServer(server, options);
2016-11-04 11:42:12 +01:00
}
2015-05-20 20:39:52 +02:00
2016-11-04 11:42:12 +01:00
/**
* Deletes all internet password keychain entries for `server`.
* @param {string} server URL to server.
* @param {object} options Keychain options, iOS only
* @return {Promise} Resolves to `true` when successful
2016-11-04 11:42:12 +01:00
*/
export function resetInternetCredentials(
server: string,
options?: Options
): Promise<void> {
return RNKeychainManager.resetInternetCredentialsForServer(server, options);
}
function getOptionsArgument(serviceOrOptions?: string | Options) {
if (Platform.OS !== 'ios') {
return typeof serviceOrOptions === 'object'
? serviceOrOptions.service
: serviceOrOptions;
}
return typeof serviceOrOptions === 'string'
? { service: serviceOrOptions }
: serviceOrOptions;
2016-11-04 11:42:12 +01:00
}
2015-05-20 18:23:04 +02:00
function getMinimumSecurityLevel(serviceOrOptions?: string | Options) {
2019-01-20 21:24:48 +01:00
var specifiedLevel = undefined;
if (typeof serviceOrOptions === 'object') {
specifiedLevel = serviceOrOptions.securityLevel;
}
return specifiedLevel || SECURITY_LEVEL.ANY;
}
2016-11-04 11:42:12 +01:00
/**
* 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 {string|object} serviceOrOptions Reverse domain name qualifier for the service, defaults to `bundleId` or an options object.
* @return {Promise} Resolves to `true` when successful
2016-11-04 11:42:12 +01:00
*/
export function setGenericPassword(
username: string,
password: string,
serviceOrOptions?: string | Options
): Promise<boolean> {
return RNKeychainManager.setGenericPasswordForOptions(
getOptionsArgument(serviceOrOptions),
username,
password,
getMinimumSecurityLevel(serviceOrOptions)
);
2016-11-04 11:42:12 +01:00
}
2015-05-29 18:25:56 +02:00
export type SharedWebCredentials = {|
+server: string,
+username: string,
+password: string,
|};
2016-11-04 11:42:12 +01:00
/**
* Fetches login combination for `service`.
* @param {string|object} serviceOrOptions Reverse domain name qualifier for the service, defaults to `bundleId` or an options object.
* @return {Promise} Resolves to `{ service, username, password }` when successful
2016-11-04 11:42:12 +01:00
*/
export function getGenericPassword(
serviceOrOptions?: string | Options
): Promise<boolean | SharedWebCredentials> {
return RNKeychainManager.getGenericPasswordForOptions(
getOptionsArgument(serviceOrOptions)
);
2016-11-04 11:42:12 +01:00
}
2015-05-29 18:25:56 +02:00
2016-11-04 11:42:12 +01:00
/**
* Deletes all generic password keychain entries for `service`.
* @param {string|object} serviceOrOptions Reverse domain name qualifier for the service, defaults to `bundleId` or an options object.
* @return {Promise} Resolves to `true` when successful
2016-11-04 11:42:12 +01:00
*/
export function resetGenericPassword(
serviceOrOptions?: string | Options
): Promise<boolean> {
return RNKeychainManager.resetGenericPasswordForOptions(
getOptionsArgument(serviceOrOptions)
);
2015-05-20 20:39:52 +02:00
}
/**
* Asks the user for a shared web credential.
* @return {Promise} Resolves to `{ server, username, password }` if approved and
* `false` if denied and throws an error if not supported on platform or there's no shared credentials
*/
export function requestSharedWebCredentials(): Promise<SharedWebCredentials> {
if (Platform.OS !== 'ios') {
return Promise.reject(
new Error(
`requestSharedWebCredentials() is not supported on ${Platform.OS} yet`
)
);
}
return RNKeychainManager.requestSharedWebCredentials();
}
/**
* Sets a shared web credential.
* @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.
* @return {Promise} Resolves to `true` when successful
*/
export function setSharedWebCredentials(
server: string,
username: string,
password: string
): Promise<void> {
if (Platform.OS !== 'ios') {
return Promise.reject(
new Error(
`setSharedWebCredentials() is not supported on ${Platform.OS} yet`
)
);
}
return RNKeychainManager.setSharedWebCredentialsForServer(
server,
username,
password
);
}