expo-secure-store 10.0.0 β 11.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -3
- package/android/build.gradle +27 -17
- package/android/src/main/java/expo/modules/securestore/SecureStoreModule.java +5 -5
- package/android/src/main/java/expo/modules/securestore/SecureStorePackage.java +2 -2
- package/build/ExpoSecureStore.d.ts +1 -1
- package/build/ExpoSecureStore.js +1 -1
- package/build/ExpoSecureStore.js.map +1 -1
- package/build/SecureStore.d.ts +68 -2
- package/build/SecureStore.js +70 -3
- package/build/SecureStore.js.map +1 -1
- package/ios/EXSecureStore/EXSecureStore.h +3 -3
- package/ios/EXSecureStore/EXSecureStore.m +15 -15
- package/ios/EXSecureStore.podspec +3 -2
- package/package.json +6 -6
- package/src/ExpoSecureStore.ts +1 -1
- package/src/SecureStore.ts +87 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,15 +8,50 @@
|
|
|
8
8
|
|
|
9
9
|
### π Bug fixes
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### π‘ Others
|
|
12
|
+
|
|
13
|
+
## 11.0.1 β 2021-10-01
|
|
12
14
|
|
|
13
15
|
_This version does not introduce any user-facing changes._
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## 11.0.0 β 2021-09-28
|
|
16
18
|
|
|
17
19
|
### π Breaking changes
|
|
18
20
|
|
|
19
|
-
- Dropped support for iOS
|
|
21
|
+
- Dropped support for iOS 11.0 ([#14383](https://github.com/expo/expo/pull/14383) by [@cruzach](https://github.com/cruzach))
|
|
22
|
+
|
|
23
|
+
### π Bug fixes
|
|
24
|
+
|
|
25
|
+
- Fix building errors from use_frameworks! in Podfile. ([#14523](https://github.com/expo/expo/pull/14523) by [@kudo](https://github.com/kudo))
|
|
26
|
+
|
|
27
|
+
### π‘ Others
|
|
28
|
+
|
|
29
|
+
- Migrated from `@unimodules/core` to `expo-modules-core`. ([#13757](https://github.com/expo/expo/pull/13757) by [@tsapeta](https://github.com/tsapeta))
|
|
30
|
+
|
|
31
|
+
## 10.2.0 β 2021-06-16
|
|
32
|
+
|
|
33
|
+
### π Bug fixes
|
|
34
|
+
|
|
35
|
+
- Enable kotlin in all modules. ([#12716](https://github.com/expo/expo/pull/12716) by [@wschurman](https://github.com/wschurman))
|
|
36
|
+
|
|
37
|
+
### π‘ Others
|
|
38
|
+
|
|
39
|
+
- Build Android code using Java 8 to fix Android instrumented test build error. ([#12939](https://github.com/expo/expo/pull/12939) by [@kudo](https://github.com/kudo))
|
|
40
|
+
|
|
41
|
+
## 10.1.0 β 2021-03-10
|
|
42
|
+
|
|
43
|
+
### π New features
|
|
44
|
+
|
|
45
|
+
- Updated Android build configuration to target Android 11 (added support for Android SDK 30). ([#11647](https://github.com/expo/expo/pull/11647) by [@bbarthec](https://github.com/bbarthec))
|
|
46
|
+
|
|
47
|
+
### π Bug fixes
|
|
48
|
+
|
|
49
|
+
- Data saved with `expo-secure-store` is no longer lost upon ejecting, **if you first upgrade your app to SDK 41 before ejecting**. ([#11309](https://github.com/expo/expo/pull/11309) by [@cruzach](https://github.com/cruzach))
|
|
50
|
+
> On Android, all of your `SecureStore` data will be migrated on app start-up. On iOS, keys and their associated data will be migrated whenever you call `getItemAsync` on that key. This means that any keys you don't `get` while on SDK 41 will **not** be migrated.
|
|
51
|
+
|
|
52
|
+
## 10.0.0 β 2021-01-15
|
|
53
|
+
|
|
54
|
+
### π Breaking changes- Dropped support for iOS 10.0 ([#11344](https://github.com/expo/expo/pull/11344) by [@tsapeta](https://github.com/tsapeta))
|
|
20
55
|
|
|
21
56
|
## 9.3.0 β 2020-11-17
|
|
22
57
|
|
package/android/build.gradle
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
|
+
apply plugin: 'kotlin-android'
|
|
2
3
|
apply plugin: 'maven'
|
|
3
4
|
|
|
4
5
|
group = 'host.exp.exponent'
|
|
5
|
-
version = '
|
|
6
|
+
version = '11.0.1'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
buildscript {
|
|
9
|
+
// Simple helper that allows the root project to override versions declared by this library.
|
|
10
|
+
ext.safeExtGet = { prop, fallback ->
|
|
11
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
repositories {
|
|
15
|
+
mavenCentral()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
dependencies {
|
|
19
|
+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', '1.4.21')}")
|
|
20
|
+
}
|
|
10
21
|
}
|
|
11
22
|
|
|
12
23
|
// Upload android library to maven with javadoc and android sources
|
|
@@ -35,27 +46,26 @@ uploadArchives {
|
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
android {
|
|
38
|
-
compileSdkVersion safeExtGet("compileSdkVersion",
|
|
49
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 30)
|
|
50
|
+
|
|
51
|
+
compileOptions {
|
|
52
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
53
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
54
|
+
}
|
|
39
55
|
|
|
40
56
|
defaultConfig {
|
|
41
57
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
42
|
-
targetSdkVersion safeExtGet("targetSdkVersion",
|
|
43
|
-
versionCode
|
|
44
|
-
versionName '
|
|
58
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 30)
|
|
59
|
+
versionCode 17
|
|
60
|
+
versionName '11.0.1'
|
|
45
61
|
}
|
|
46
62
|
lintOptions {
|
|
47
63
|
abortOnError false
|
|
48
64
|
}
|
|
49
65
|
}
|
|
50
66
|
|
|
51
|
-
if (new File(rootProject.projectDir.parentFile, 'package.json').exists()) {
|
|
52
|
-
apply from: project(':unimodules-core').file('../unimodules-core.gradle')
|
|
53
|
-
} else {
|
|
54
|
-
throw new GradleException(
|
|
55
|
-
'\'unimodules-core.gradle\' was not found in the usual React Native dependency location. ' +
|
|
56
|
-
'This package can only be used in such projects. Are you sure you\'ve installed the dependencies properly?')
|
|
57
|
-
}
|
|
58
|
-
|
|
59
67
|
dependencies {
|
|
60
|
-
|
|
68
|
+
implementation project(':expo-modules-core')
|
|
69
|
+
|
|
70
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${safeExtGet('kotlinVersion', '1.4.21')}"
|
|
61
71
|
}
|
|
@@ -15,10 +15,10 @@ import android.util.Log;
|
|
|
15
15
|
|
|
16
16
|
import org.json.JSONException;
|
|
17
17
|
import org.json.JSONObject;
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
18
|
+
import expo.modules.core.ExportedModule;
|
|
19
|
+
import expo.modules.core.Promise;
|
|
20
|
+
import expo.modules.core.arguments.ReadableArguments;
|
|
21
|
+
import expo.modules.core.interfaces.ExpoMethod;
|
|
22
22
|
|
|
23
23
|
import java.io.IOException;
|
|
24
24
|
import java.math.BigInteger;
|
|
@@ -296,7 +296,7 @@ public class SecureStoreModule extends ExportedModule {
|
|
|
296
296
|
* We use a shared preferences file that's scoped to both the experience and SecureStore. This
|
|
297
297
|
* lets us easily list or remove all the entries for an experience.
|
|
298
298
|
*/
|
|
299
|
-
|
|
299
|
+
protected SharedPreferences getSharedPreferences() {
|
|
300
300
|
return getContext().getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
|
301
301
|
}
|
|
302
302
|
|
|
@@ -5,8 +5,8 @@ import android.content.Context;
|
|
|
5
5
|
import java.util.Collections;
|
|
6
6
|
import java.util.List;
|
|
7
7
|
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import expo.modules.core.BasePackage;
|
|
9
|
+
import expo.modules.core.ExportedModule;
|
|
10
10
|
|
|
11
11
|
public class SecureStorePackage extends BasePackage {
|
|
12
12
|
@Override
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("
|
|
1
|
+
declare const _default: import("expo-modules-core").ProxyNativeModule;
|
|
2
2
|
export default _default;
|
package/build/ExpoSecureStore.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoSecureStore.js","sourceRoot":"","sources":["../src/ExpoSecureStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ExpoSecureStore.js","sourceRoot":"","sources":["../src/ExpoSecureStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,eAAe,kBAAkB,CAAC,eAAe,IAAI,EAAE,CAAC","sourcesContent":["import { NativeModulesProxy } from 'expo-modules-core';\nexport default NativeModulesProxy.ExpoSecureStore || {};\n"]}
|
package/build/SecureStore.d.ts
CHANGED
|
@@ -1,21 +1,87 @@
|
|
|
1
1
|
export declare type KeychainAccessibilityConstant = number;
|
|
2
|
+
/**
|
|
3
|
+
* The data in the keychain item cannot be accessed after a restart until the device has been
|
|
4
|
+
* unlocked once by the user. This may be useful if you need to access the item when the phone
|
|
5
|
+
* is locked.
|
|
6
|
+
*/
|
|
2
7
|
export declare const AFTER_FIRST_UNLOCK: KeychainAccessibilityConstant;
|
|
8
|
+
/**
|
|
9
|
+
* Similar to `AFTER_FIRST_UNLOCK`, except the entry is not migrated to a new device when restoring
|
|
10
|
+
* from a backup.
|
|
11
|
+
*/
|
|
3
12
|
export declare const AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;
|
|
13
|
+
/**
|
|
14
|
+
* The data in the keychain item can always be accessed regardless of whether the device is locked.
|
|
15
|
+
* This is the least secure option.
|
|
16
|
+
*/
|
|
4
17
|
export declare const ALWAYS: KeychainAccessibilityConstant;
|
|
18
|
+
/**
|
|
19
|
+
* Similar to `WHEN_UNLOCKED_THIS_DEVICE_ONLY`, except the user must have set a passcode in order to
|
|
20
|
+
* store an entry. If the user removes their passcode, the entry will be deleted.
|
|
21
|
+
*/
|
|
5
22
|
export declare const WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;
|
|
23
|
+
/**
|
|
24
|
+
* Similar to `ALWAYS`, except the entry is not migrated to a new device when restoring from a backup.
|
|
25
|
+
*/
|
|
6
26
|
export declare const ALWAYS_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;
|
|
27
|
+
/**
|
|
28
|
+
* The data in the keychain item can be accessed only while the device is unlocked by the user.
|
|
29
|
+
*/
|
|
7
30
|
export declare const WHEN_UNLOCKED: KeychainAccessibilityConstant;
|
|
31
|
+
/**
|
|
32
|
+
* Similar to `WHEN_UNLOCKED`, except the entry is not migrated to a new device when restoring from
|
|
33
|
+
* a backup.
|
|
34
|
+
*/
|
|
8
35
|
export declare const WHEN_UNLOCKED_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;
|
|
9
36
|
export declare type SecureStoreOptions = {
|
|
37
|
+
/**
|
|
38
|
+
* - iOS: The item's service, equivalent to `kSecAttrService`
|
|
39
|
+
* - Android: Equivalent of the public/private key pair `Alias`
|
|
40
|
+
* > If the item is set with the `keychainService` option, it will be required to later fetch the value.
|
|
41
|
+
*/
|
|
10
42
|
keychainService?: string;
|
|
43
|
+
/**
|
|
44
|
+
* __(iOS only)__ Specifies when the stored entry is accessible, using iOS's `kSecAttrAccessible`
|
|
45
|
+
* property. See Apple's documentation on [keychain item accessibility](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-SW18).
|
|
46
|
+
* Default value: `SecureStore.WHEN_UNLOCKED`.
|
|
47
|
+
*/
|
|
11
48
|
keychainAccessible?: KeychainAccessibilityConstant;
|
|
12
49
|
};
|
|
13
50
|
/**
|
|
14
|
-
* Returns whether the SecureStore API is enabled on the current device. This does not check the app
|
|
51
|
+
* Returns whether the SecureStore API is enabled on the current device. This does not check the app
|
|
52
|
+
* permissions.
|
|
15
53
|
*
|
|
16
|
-
* @
|
|
54
|
+
* @return Promise which fulfils witch `boolean`, indicating whether the SecureStore API is available
|
|
55
|
+
* on the current device. Currently this resolves `true` on iOS and Android only.
|
|
17
56
|
*/
|
|
18
57
|
export declare function isAvailableAsync(): Promise<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* Delete the value associated with the provided key.
|
|
60
|
+
*
|
|
61
|
+
* @param key The key that was used to store the associated value.
|
|
62
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
63
|
+
*
|
|
64
|
+
* @return A promise that will reject if the value couldn't be deleted.
|
|
65
|
+
*/
|
|
19
66
|
export declare function deleteItemAsync(key: string, options?: SecureStoreOptions): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Fetch the stored value associated with the provided key.
|
|
69
|
+
*
|
|
70
|
+
* @param key The key that was used to store the associated value.
|
|
71
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
72
|
+
*
|
|
73
|
+
* @return A promise that resolves to the previously stored value, or `null` if there is no entry
|
|
74
|
+
* for the given key. The promise will reject if an error occurred while retrieving the value.
|
|
75
|
+
*/
|
|
20
76
|
export declare function getItemAsync(key: string, options?: SecureStoreOptions): Promise<string | null>;
|
|
77
|
+
/**
|
|
78
|
+
* Store a keyβvalue pair.
|
|
79
|
+
*
|
|
80
|
+
* @param key The key to associate with the stored value. Keys may contain alphanumeric characters
|
|
81
|
+
* `.`, `-`, and `_`.
|
|
82
|
+
* @param value The value to store. Size limit is 2048 bytes.
|
|
83
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
84
|
+
*
|
|
85
|
+
* @return A promise that will reject if value cannot be stored on the device.
|
|
86
|
+
*/
|
|
21
87
|
export declare function setItemAsync(key: string, value: string, options?: SecureStoreOptions): Promise<void>;
|
package/build/SecureStore.js
CHANGED
|
@@ -1,21 +1,67 @@
|
|
|
1
|
-
import { UnavailabilityError } from '
|
|
1
|
+
import { UnavailabilityError } from 'expo-modules-core';
|
|
2
2
|
import ExpoSecureStore from './ExpoSecureStore';
|
|
3
|
+
// @needsAudit
|
|
4
|
+
/**
|
|
5
|
+
* The data in the keychain item cannot be accessed after a restart until the device has been
|
|
6
|
+
* unlocked once by the user. This may be useful if you need to access the item when the phone
|
|
7
|
+
* is locked.
|
|
8
|
+
*/
|
|
3
9
|
export const AFTER_FIRST_UNLOCK = ExpoSecureStore.AFTER_FIRST_UNLOCK;
|
|
10
|
+
// @needsAudit
|
|
11
|
+
/**
|
|
12
|
+
* Similar to `AFTER_FIRST_UNLOCK`, except the entry is not migrated to a new device when restoring
|
|
13
|
+
* from a backup.
|
|
14
|
+
*/
|
|
4
15
|
export const AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY = ExpoSecureStore.AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY;
|
|
16
|
+
// @needsAudit
|
|
17
|
+
/**
|
|
18
|
+
* The data in the keychain item can always be accessed regardless of whether the device is locked.
|
|
19
|
+
* This is the least secure option.
|
|
20
|
+
*/
|
|
5
21
|
export const ALWAYS = ExpoSecureStore.ALWAYS;
|
|
22
|
+
// @needsAudit
|
|
23
|
+
/**
|
|
24
|
+
* Similar to `WHEN_UNLOCKED_THIS_DEVICE_ONLY`, except the user must have set a passcode in order to
|
|
25
|
+
* store an entry. If the user removes their passcode, the entry will be deleted.
|
|
26
|
+
*/
|
|
6
27
|
export const WHEN_PASSCODE_SET_THIS_DEVICE_ONLY = ExpoSecureStore.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY;
|
|
28
|
+
// @needsAudit
|
|
29
|
+
/**
|
|
30
|
+
* Similar to `ALWAYS`, except the entry is not migrated to a new device when restoring from a backup.
|
|
31
|
+
*/
|
|
7
32
|
export const ALWAYS_THIS_DEVICE_ONLY = ExpoSecureStore.ALWAYS_THIS_DEVICE_ONLY;
|
|
33
|
+
// @needsAudit
|
|
34
|
+
/**
|
|
35
|
+
* The data in the keychain item can be accessed only while the device is unlocked by the user.
|
|
36
|
+
*/
|
|
8
37
|
export const WHEN_UNLOCKED = ExpoSecureStore.WHEN_UNLOCKED;
|
|
38
|
+
// @needsAudit
|
|
39
|
+
/**
|
|
40
|
+
* Similar to `WHEN_UNLOCKED`, except the entry is not migrated to a new device when restoring from
|
|
41
|
+
* a backup.
|
|
42
|
+
*/
|
|
9
43
|
export const WHEN_UNLOCKED_THIS_DEVICE_ONLY = ExpoSecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY;
|
|
10
44
|
const VALUE_BYTES_LIMIT = 2048;
|
|
45
|
+
// @needsAudit
|
|
11
46
|
/**
|
|
12
|
-
* Returns whether the SecureStore API is enabled on the current device. This does not check the app
|
|
47
|
+
* Returns whether the SecureStore API is enabled on the current device. This does not check the app
|
|
48
|
+
* permissions.
|
|
13
49
|
*
|
|
14
|
-
* @
|
|
50
|
+
* @return Promise which fulfils witch `boolean`, indicating whether the SecureStore API is available
|
|
51
|
+
* on the current device. Currently this resolves `true` on iOS and Android only.
|
|
15
52
|
*/
|
|
16
53
|
export async function isAvailableAsync() {
|
|
17
54
|
return !!ExpoSecureStore.getValueWithKeyAsync;
|
|
18
55
|
}
|
|
56
|
+
// @needsAudit
|
|
57
|
+
/**
|
|
58
|
+
* Delete the value associated with the provided key.
|
|
59
|
+
*
|
|
60
|
+
* @param key The key that was used to store the associated value.
|
|
61
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
62
|
+
*
|
|
63
|
+
* @return A promise that will reject if the value couldn't be deleted.
|
|
64
|
+
*/
|
|
19
65
|
export async function deleteItemAsync(key, options = {}) {
|
|
20
66
|
_ensureValidKey(key);
|
|
21
67
|
if (!ExpoSecureStore.deleteValueWithKeyAsync) {
|
|
@@ -23,10 +69,31 @@ export async function deleteItemAsync(key, options = {}) {
|
|
|
23
69
|
}
|
|
24
70
|
await ExpoSecureStore.deleteValueWithKeyAsync(key, options);
|
|
25
71
|
}
|
|
72
|
+
// @needsAudit
|
|
73
|
+
/**
|
|
74
|
+
* Fetch the stored value associated with the provided key.
|
|
75
|
+
*
|
|
76
|
+
* @param key The key that was used to store the associated value.
|
|
77
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
78
|
+
*
|
|
79
|
+
* @return A promise that resolves to the previously stored value, or `null` if there is no entry
|
|
80
|
+
* for the given key. The promise will reject if an error occurred while retrieving the value.
|
|
81
|
+
*/
|
|
26
82
|
export async function getItemAsync(key, options = {}) {
|
|
27
83
|
_ensureValidKey(key);
|
|
28
84
|
return await ExpoSecureStore.getValueWithKeyAsync(key, options);
|
|
29
85
|
}
|
|
86
|
+
// @needsAudit
|
|
87
|
+
/**
|
|
88
|
+
* Store a keyβvalue pair.
|
|
89
|
+
*
|
|
90
|
+
* @param key The key to associate with the stored value. Keys may contain alphanumeric characters
|
|
91
|
+
* `.`, `-`, and `_`.
|
|
92
|
+
* @param value The value to store. Size limit is 2048 bytes.
|
|
93
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
94
|
+
*
|
|
95
|
+
* @return A promise that will reject if value cannot be stored on the device.
|
|
96
|
+
*/
|
|
30
97
|
export async function setItemAsync(key, value, options = {}) {
|
|
31
98
|
_ensureValidKey(key);
|
|
32
99
|
if (!_isValidValue(value)) {
|
package/build/SecureStore.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecureStore.js","sourceRoot":"","sources":["../src/SecureStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"SecureStore.js","sourceRoot":"","sources":["../src/SecureStore.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport ExpoSecureStore from './ExpoSecureStore';\n\nexport type KeychainAccessibilityConstant = number;\n\n// @needsAudit\n/**\n * The data in the keychain item cannot be accessed after a restart until the device has been\n * unlocked once by the user. This may be useful if you need to access the item when the phone\n * is locked.\n */\nexport const AFTER_FIRST_UNLOCK: KeychainAccessibilityConstant = ExpoSecureStore.AFTER_FIRST_UNLOCK;\n\n// @needsAudit\n/**\n * Similar to `AFTER_FIRST_UNLOCK`, except the entry is not migrated to a new device when restoring\n * from a backup.\n */\nexport const AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =\n ExpoSecureStore.AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY;\n\n// @needsAudit\n/**\n * The data in the keychain item can always be accessed regardless of whether the device is locked.\n * This is the least secure option.\n */\nexport const ALWAYS: KeychainAccessibilityConstant = ExpoSecureStore.ALWAYS;\n\n// @needsAudit\n/**\n * Similar to `WHEN_UNLOCKED_THIS_DEVICE_ONLY`, except the user must have set a passcode in order to\n * store an entry. If the user removes their passcode, the entry will be deleted.\n */\nexport const WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =\n ExpoSecureStore.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY;\n\n// @needsAudit\n/**\n * Similar to `ALWAYS`, except the entry is not migrated to a new device when restoring from a backup.\n */\nexport const ALWAYS_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =\n ExpoSecureStore.ALWAYS_THIS_DEVICE_ONLY;\n\n// @needsAudit\n/**\n * The data in the keychain item can be accessed only while the device is unlocked by the user.\n */\nexport const WHEN_UNLOCKED: KeychainAccessibilityConstant = ExpoSecureStore.WHEN_UNLOCKED;\n\n// @needsAudit\n/**\n * Similar to `WHEN_UNLOCKED`, except the entry is not migrated to a new device when restoring from\n * a backup.\n */\nexport const WHEN_UNLOCKED_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =\n ExpoSecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY;\n\nconst VALUE_BYTES_LIMIT = 2048;\n\n// @needsAudit\nexport type SecureStoreOptions = {\n /**\n * - iOS: The item's service, equivalent to `kSecAttrService`\n * - Android: Equivalent of the public/private key pair `Alias`\n * > If the item is set with the `keychainService` option, it will be required to later fetch the value.\n */\n keychainService?: string;\n /**\n * __(iOS only)__ Specifies when the stored entry is accessible, using iOS's `kSecAttrAccessible`\n * property. See Apple's documentation on [keychain item accessibility](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-SW18).\n * Default value: `SecureStore.WHEN_UNLOCKED`.\n */\n keychainAccessible?: KeychainAccessibilityConstant;\n};\n\n// @needsAudit\n/**\n * Returns whether the SecureStore API is enabled on the current device. This does not check the app\n * permissions.\n *\n * @return Promise which fulfils witch `boolean`, indicating whether the SecureStore API is available\n * on the current device. Currently this resolves `true` on iOS and Android only.\n */\nexport async function isAvailableAsync(): Promise<boolean> {\n return !!ExpoSecureStore.getValueWithKeyAsync;\n}\n\n// @needsAudit\n/**\n * Delete the value associated with the provided key.\n *\n * @param key The key that was used to store the associated value.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n * @return A promise that will reject if the value couldn't be deleted.\n */\nexport async function deleteItemAsync(\n key: string,\n options: SecureStoreOptions = {}\n): Promise<void> {\n _ensureValidKey(key);\n\n if (!ExpoSecureStore.deleteValueWithKeyAsync) {\n throw new UnavailabilityError('SecureStore', 'deleteItemAsync');\n }\n await ExpoSecureStore.deleteValueWithKeyAsync(key, options);\n}\n\n// @needsAudit\n/**\n * Fetch the stored value associated with the provided key.\n *\n * @param key The key that was used to store the associated value.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n * @return A promise that resolves to the previously stored value, or `null` if there is no entry\n * for the given key. The promise will reject if an error occurred while retrieving the value.\n */\nexport async function getItemAsync(\n key: string,\n options: SecureStoreOptions = {}\n): Promise<string | null> {\n _ensureValidKey(key);\n return await ExpoSecureStore.getValueWithKeyAsync(key, options);\n}\n\n// @needsAudit\n/**\n * Store a keyβvalue pair.\n *\n * @param key The key to associate with the stored value. Keys may contain alphanumeric characters\n * `.`, `-`, and `_`.\n * @param value The value to store. Size limit is 2048 bytes.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n * @return A promise that will reject if value cannot be stored on the device.\n */\nexport async function setItemAsync(\n key: string,\n value: string,\n options: SecureStoreOptions = {}\n): Promise<void> {\n _ensureValidKey(key);\n if (!_isValidValue(value)) {\n throw new Error(\n `Invalid value provided to SecureStore. Values must be strings; consider JSON-encoding your values if they are serializable.`\n );\n }\n if (!ExpoSecureStore.setValueWithKeyAsync) {\n throw new UnavailabilityError('SecureStore', 'setItemAsync');\n }\n await ExpoSecureStore.setValueWithKeyAsync(value, key, options);\n}\n\nfunction _ensureValidKey(key: string) {\n if (!_isValidKey(key)) {\n throw new Error(\n `Invalid key provided to SecureStore. Keys must not be empty and contain only alphanumeric characters, \".\", \"-\", and \"_\".`\n );\n }\n}\n\nfunction _isValidKey(key: string) {\n return typeof key === 'string' && /^[\\w.-]+$/.test(key);\n}\n\nfunction _isValidValue(value: string) {\n if (typeof value !== 'string') {\n return false;\n }\n if (_byteCount(value) > VALUE_BYTES_LIMIT) {\n console.warn(\n 'Provided value to SecureStore is larger than 2048 bytes. An attempt to store such a value will throw an error in SDK 35.'\n );\n }\n return true;\n}\n\n// copy-pasted from https://stackoverflow.com/a/39488643\nfunction _byteCount(value: string) {\n let bytes = 0;\n\n for (let i = 0; i < value.length; i++) {\n const codePoint = value.charCodeAt(i);\n\n // Lone surrogates cannot be passed to encodeURI\n if (codePoint >= 0xd800 && codePoint < 0xe000) {\n if (codePoint < 0xdc00 && i + 1 < value.length) {\n const next = value.charCodeAt(i + 1);\n\n if (next >= 0xdc00 && next < 0xe000) {\n bytes += 4;\n i++;\n continue;\n }\n }\n }\n\n bytes += codePoint < 0x80 ? 1 : codePoint < 0x800 ? 2 : 3;\n }\n\n return bytes;\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright Β© 2018 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
|
-
#import <
|
|
4
|
-
#import <
|
|
3
|
+
#import <ExpoModulesCore/EXExportedModule.h>
|
|
4
|
+
#import <ExpoModulesCore/EXModuleRegistryConsumer.h>
|
|
5
5
|
|
|
6
6
|
typedef NS_ENUM(NSInteger, EXSecureStoreAccessible) {
|
|
7
7
|
EXSecureStoreAccessibleAfterFirstUnlock = 0,
|
|
@@ -13,6 +13,6 @@ typedef NS_ENUM(NSInteger, EXSecureStoreAccessible) {
|
|
|
13
13
|
EXSecureStoreAccessibleWhenUnlockedThisDeviceOnly = 6
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
@interface EXSecureStore :
|
|
16
|
+
@interface EXSecureStore : EXExportedModule
|
|
17
17
|
|
|
18
18
|
@end
|
|
@@ -200,18 +200,18 @@
|
|
|
200
200
|
};
|
|
201
201
|
};
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
EX_EXPORT_MODULE(ExpoSecureStore);
|
|
204
204
|
|
|
205
|
-
|
|
205
|
+
EX_EXPORT_METHOD_AS(setValueWithKeyAsync,
|
|
206
206
|
setValueWithKeyAsync:(NSString *)value
|
|
207
207
|
key:(NSString *)key
|
|
208
208
|
options:(NSDictionary *)options
|
|
209
|
-
resolver:(
|
|
210
|
-
rejecter:(
|
|
209
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
210
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
211
211
|
{
|
|
212
212
|
NSString *validatedKey = [self validatedKey:key];
|
|
213
213
|
if (!validatedKey) {
|
|
214
|
-
reject(@"E_SECURESTORE_SETVALUEFAIL", nil,
|
|
214
|
+
reject(@"E_SECURESTORE_SETVALUEFAIL", nil, EXErrorWithMessage(@"Invalid key."));
|
|
215
215
|
} else {
|
|
216
216
|
NSError *error;
|
|
217
217
|
BOOL setValue = [self _setValue:value
|
|
@@ -221,20 +221,20 @@ UM_EXPORT_METHOD_AS(setValueWithKeyAsync,
|
|
|
221
221
|
if (setValue) {
|
|
222
222
|
resolve(nil);
|
|
223
223
|
} else {
|
|
224
|
-
reject(@"E_SECURESTORE_SETVALUEFAIL", nil,
|
|
224
|
+
reject(@"E_SECURESTORE_SETVALUEFAIL", nil, EXErrorWithMessage([[self class] _messageForError:error]));
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
|
|
229
|
+
EX_EXPORT_METHOD_AS(getValueWithKeyAsync,
|
|
230
230
|
getValueWithKeyAsync:(NSString *)key
|
|
231
231
|
options:(NSDictionary *)options
|
|
232
|
-
resolver:(
|
|
233
|
-
rejecter:(
|
|
232
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
233
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
234
234
|
{
|
|
235
235
|
NSString *validatedKey = [self validatedKey:key];
|
|
236
236
|
if (!validatedKey) {
|
|
237
|
-
reject(@"E_SECURESTORE_GETVALUEFAIL", nil,
|
|
237
|
+
reject(@"E_SECURESTORE_GETVALUEFAIL", nil, EXErrorWithMessage(@"Invalid key."));
|
|
238
238
|
} else {
|
|
239
239
|
NSError *error;
|
|
240
240
|
NSString *value = [self _getValueWithKey:validatedKey
|
|
@@ -244,7 +244,7 @@ UM_EXPORT_METHOD_AS(getValueWithKeyAsync,
|
|
|
244
244
|
if (error.code == errSecItemNotFound) {
|
|
245
245
|
resolve([NSNull null]);
|
|
246
246
|
} else {
|
|
247
|
-
reject(@"E_SECURESTORE_GETVALUEFAIL", nil,
|
|
247
|
+
reject(@"E_SECURESTORE_GETVALUEFAIL", nil, EXErrorWithMessage([[self class] _messageForError:error]));
|
|
248
248
|
}
|
|
249
249
|
} else {
|
|
250
250
|
resolve(value);
|
|
@@ -252,15 +252,15 @@ UM_EXPORT_METHOD_AS(getValueWithKeyAsync,
|
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
|
|
255
|
+
EX_EXPORT_METHOD_AS(deleteValueWithKeyAsync,
|
|
256
256
|
deleteValueWithKeyAsync:(NSString *)key
|
|
257
257
|
options:(NSDictionary *)options
|
|
258
|
-
resolver:(
|
|
259
|
-
rejecter:(
|
|
258
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
259
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
260
260
|
{
|
|
261
261
|
NSString *validatedKey = [self validatedKey:key];
|
|
262
262
|
if (!validatedKey) {
|
|
263
|
-
reject(@"E_SECURESTORE_DELETEVALUEFAIL", nil,
|
|
263
|
+
reject(@"E_SECURESTORE_DELETEVALUEFAIL", nil, EXErrorWithMessage(@"Invalid key."));
|
|
264
264
|
} else {
|
|
265
265
|
[self _deleteValueWithKey:validatedKey
|
|
266
266
|
withOptions:options];
|
|
@@ -10,10 +10,11 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.license = package['license']
|
|
11
11
|
s.author = package['author']
|
|
12
12
|
s.homepage = package['homepage']
|
|
13
|
-
s.platform = :ios, '
|
|
13
|
+
s.platform = :ios, '12.0'
|
|
14
14
|
s.source = { git: 'https://github.com/expo/expo.git' }
|
|
15
|
+
s.static_framework = true
|
|
15
16
|
|
|
16
|
-
s.dependency '
|
|
17
|
+
s.dependency 'ExpoModulesCore'
|
|
17
18
|
|
|
18
19
|
if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
|
|
19
20
|
s.source_files = "#{s.name}/**/*.h"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-secure-store",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.1",
|
|
4
4
|
"description": "Provides a way to encrypt and securely store keyβvalue pairs locally on the device.",
|
|
5
5
|
"main": "build/SecureStore.js",
|
|
6
6
|
"types": "build/SecureStore.d.ts",
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
},
|
|
32
32
|
"author": "650 Industries, Inc.",
|
|
33
33
|
"license": "MIT",
|
|
34
|
-
"homepage": "https://docs.expo.
|
|
34
|
+
"homepage": "https://docs.expo.dev/versions/latest/sdk/securestore/",
|
|
35
35
|
"jest": {
|
|
36
36
|
"preset": "expo-module-scripts"
|
|
37
37
|
},
|
|
38
|
-
"
|
|
39
|
-
"
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"expo-modules-core": "~0.4.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"expo-module-scripts": "
|
|
42
|
+
"expo-module-scripts": "^2.0.0"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "2718b696f4a6919905b0f47ebb24ff65b42d8ff9"
|
|
45
45
|
}
|
package/src/ExpoSecureStore.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { NativeModulesProxy } from '
|
|
1
|
+
import { NativeModulesProxy } from 'expo-modules-core';
|
|
2
2
|
export default NativeModulesProxy.ExpoSecureStore || {};
|
package/src/SecureStore.ts
CHANGED
|
@@ -1,37 +1,100 @@
|
|
|
1
|
-
import { UnavailabilityError } from '
|
|
1
|
+
import { UnavailabilityError } from 'expo-modules-core';
|
|
2
2
|
|
|
3
3
|
import ExpoSecureStore from './ExpoSecureStore';
|
|
4
4
|
|
|
5
5
|
export type KeychainAccessibilityConstant = number;
|
|
6
6
|
|
|
7
|
+
// @needsAudit
|
|
8
|
+
/**
|
|
9
|
+
* The data in the keychain item cannot be accessed after a restart until the device has been
|
|
10
|
+
* unlocked once by the user. This may be useful if you need to access the item when the phone
|
|
11
|
+
* is locked.
|
|
12
|
+
*/
|
|
7
13
|
export const AFTER_FIRST_UNLOCK: KeychainAccessibilityConstant = ExpoSecureStore.AFTER_FIRST_UNLOCK;
|
|
14
|
+
|
|
15
|
+
// @needsAudit
|
|
16
|
+
/**
|
|
17
|
+
* Similar to `AFTER_FIRST_UNLOCK`, except the entry is not migrated to a new device when restoring
|
|
18
|
+
* from a backup.
|
|
19
|
+
*/
|
|
8
20
|
export const AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =
|
|
9
21
|
ExpoSecureStore.AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY;
|
|
22
|
+
|
|
23
|
+
// @needsAudit
|
|
24
|
+
/**
|
|
25
|
+
* The data in the keychain item can always be accessed regardless of whether the device is locked.
|
|
26
|
+
* This is the least secure option.
|
|
27
|
+
*/
|
|
10
28
|
export const ALWAYS: KeychainAccessibilityConstant = ExpoSecureStore.ALWAYS;
|
|
29
|
+
|
|
30
|
+
// @needsAudit
|
|
31
|
+
/**
|
|
32
|
+
* Similar to `WHEN_UNLOCKED_THIS_DEVICE_ONLY`, except the user must have set a passcode in order to
|
|
33
|
+
* store an entry. If the user removes their passcode, the entry will be deleted.
|
|
34
|
+
*/
|
|
11
35
|
export const WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =
|
|
12
36
|
ExpoSecureStore.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY;
|
|
37
|
+
|
|
38
|
+
// @needsAudit
|
|
39
|
+
/**
|
|
40
|
+
* Similar to `ALWAYS`, except the entry is not migrated to a new device when restoring from a backup.
|
|
41
|
+
*/
|
|
13
42
|
export const ALWAYS_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =
|
|
14
43
|
ExpoSecureStore.ALWAYS_THIS_DEVICE_ONLY;
|
|
44
|
+
|
|
45
|
+
// @needsAudit
|
|
46
|
+
/**
|
|
47
|
+
* The data in the keychain item can be accessed only while the device is unlocked by the user.
|
|
48
|
+
*/
|
|
15
49
|
export const WHEN_UNLOCKED: KeychainAccessibilityConstant = ExpoSecureStore.WHEN_UNLOCKED;
|
|
50
|
+
|
|
51
|
+
// @needsAudit
|
|
52
|
+
/**
|
|
53
|
+
* Similar to `WHEN_UNLOCKED`, except the entry is not migrated to a new device when restoring from
|
|
54
|
+
* a backup.
|
|
55
|
+
*/
|
|
16
56
|
export const WHEN_UNLOCKED_THIS_DEVICE_ONLY: KeychainAccessibilityConstant =
|
|
17
57
|
ExpoSecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY;
|
|
18
58
|
|
|
19
59
|
const VALUE_BYTES_LIMIT = 2048;
|
|
20
60
|
|
|
61
|
+
// @needsAudit
|
|
21
62
|
export type SecureStoreOptions = {
|
|
63
|
+
/**
|
|
64
|
+
* - iOS: The item's service, equivalent to `kSecAttrService`
|
|
65
|
+
* - Android: Equivalent of the public/private key pair `Alias`
|
|
66
|
+
* > If the item is set with the `keychainService` option, it will be required to later fetch the value.
|
|
67
|
+
*/
|
|
22
68
|
keychainService?: string;
|
|
69
|
+
/**
|
|
70
|
+
* __(iOS only)__ Specifies when the stored entry is accessible, using iOS's `kSecAttrAccessible`
|
|
71
|
+
* property. See Apple's documentation on [keychain item accessibility](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-SW18).
|
|
72
|
+
* Default value: `SecureStore.WHEN_UNLOCKED`.
|
|
73
|
+
*/
|
|
23
74
|
keychainAccessible?: KeychainAccessibilityConstant;
|
|
24
75
|
};
|
|
25
76
|
|
|
77
|
+
// @needsAudit
|
|
26
78
|
/**
|
|
27
|
-
* Returns whether the SecureStore API is enabled on the current device. This does not check the app
|
|
79
|
+
* Returns whether the SecureStore API is enabled on the current device. This does not check the app
|
|
80
|
+
* permissions.
|
|
28
81
|
*
|
|
29
|
-
* @
|
|
82
|
+
* @return Promise which fulfils witch `boolean`, indicating whether the SecureStore API is available
|
|
83
|
+
* on the current device. Currently this resolves `true` on iOS and Android only.
|
|
30
84
|
*/
|
|
31
85
|
export async function isAvailableAsync(): Promise<boolean> {
|
|
32
86
|
return !!ExpoSecureStore.getValueWithKeyAsync;
|
|
33
87
|
}
|
|
34
88
|
|
|
89
|
+
// @needsAudit
|
|
90
|
+
/**
|
|
91
|
+
* Delete the value associated with the provided key.
|
|
92
|
+
*
|
|
93
|
+
* @param key The key that was used to store the associated value.
|
|
94
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
95
|
+
*
|
|
96
|
+
* @return A promise that will reject if the value couldn't be deleted.
|
|
97
|
+
*/
|
|
35
98
|
export async function deleteItemAsync(
|
|
36
99
|
key: string,
|
|
37
100
|
options: SecureStoreOptions = {}
|
|
@@ -44,6 +107,16 @@ export async function deleteItemAsync(
|
|
|
44
107
|
await ExpoSecureStore.deleteValueWithKeyAsync(key, options);
|
|
45
108
|
}
|
|
46
109
|
|
|
110
|
+
// @needsAudit
|
|
111
|
+
/**
|
|
112
|
+
* Fetch the stored value associated with the provided key.
|
|
113
|
+
*
|
|
114
|
+
* @param key The key that was used to store the associated value.
|
|
115
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
116
|
+
*
|
|
117
|
+
* @return A promise that resolves to the previously stored value, or `null` if there is no entry
|
|
118
|
+
* for the given key. The promise will reject if an error occurred while retrieving the value.
|
|
119
|
+
*/
|
|
47
120
|
export async function getItemAsync(
|
|
48
121
|
key: string,
|
|
49
122
|
options: SecureStoreOptions = {}
|
|
@@ -52,6 +125,17 @@ export async function getItemAsync(
|
|
|
52
125
|
return await ExpoSecureStore.getValueWithKeyAsync(key, options);
|
|
53
126
|
}
|
|
54
127
|
|
|
128
|
+
// @needsAudit
|
|
129
|
+
/**
|
|
130
|
+
* Store a keyβvalue pair.
|
|
131
|
+
*
|
|
132
|
+
* @param key The key to associate with the stored value. Keys may contain alphanumeric characters
|
|
133
|
+
* `.`, `-`, and `_`.
|
|
134
|
+
* @param value The value to store. Size limit is 2048 bytes.
|
|
135
|
+
* @param options An [`SecureStoreOptions`](#securestoreoptions) object.
|
|
136
|
+
*
|
|
137
|
+
* @return A promise that will reject if value cannot be stored on the device.
|
|
138
|
+
*/
|
|
55
139
|
export async function setItemAsync(
|
|
56
140
|
key: string,
|
|
57
141
|
value: string,
|