expo-secure-store 15.0.8-canary-20251120-e46b3cc → 15.0.8

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/android/build.gradle +3 -3
  3. package/build/SecureStore.d.ts +2 -3
  4. package/build/SecureStore.d.ts.map +1 -1
  5. package/build/SecureStore.js +10 -3
  6. package/build/SecureStore.js.map +1 -1
  7. package/build/byteCounter.d.ts +3 -0
  8. package/build/byteCounter.d.ts.map +1 -0
  9. package/build/byteCounter.js +29 -0
  10. package/build/byteCounter.js.map +1 -0
  11. package/expo-module.config.json +1 -1
  12. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar → 15.0.8/expo.modules.securestore-15.0.8.aar} +0 -0
  13. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.aar.md5 +1 -0
  14. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.aar.sha1 +1 -0
  15. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.aar.sha256 +1 -0
  16. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.aar.sha512 +1 -0
  17. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.module → 15.0.8/expo.modules.securestore-15.0.8.module} +27 -18
  18. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.module.md5 +1 -0
  19. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.module.sha1 +1 -0
  20. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.module.sha256 +1 -0
  21. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.module.sha512 +1 -0
  22. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.pom → 15.0.8/expo.modules.securestore-15.0.8.pom} +7 -7
  23. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.pom.md5 +1 -0
  24. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.pom.sha1 +1 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.pom.sha256 +1 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8/expo.modules.securestore-15.0.8.pom.sha512 +1 -0
  27. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/maven-metadata.xml +4 -4
  28. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/maven-metadata.xml.md5 +1 -1
  29. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/maven-metadata.xml.sha1 +1 -1
  30. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/maven-metadata.xml.sha256 +1 -1
  31. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/maven-metadata.xml.sha512 +1 -1
  32. package/package.json +5 -4
  33. package/src/SecureStore.ts +12 -4
  34. package/src/byteCounter.ts +34 -0
  35. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar.md5 +0 -1
  36. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar.sha1 +0 -1
  37. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar.sha256 +0 -1
  38. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar.sha512 +0 -1
  39. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.module.md5 +0 -1
  40. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.module.sha1 +0 -1
  41. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.module.sha256 +0 -1
  42. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.module.sha512 +0 -1
  43. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.pom.md5 +0 -1
  44. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.pom.sha1 +0 -1
  45. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.pom.sha256 +0 -1
  46. package/local-maven-repo/host/exp/exponent/expo.modules.securestore/15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.pom.sha512 +0 -1
  47. /package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc-sources.jar → 15.0.8/expo.modules.securestore-15.0.8-sources.jar} +0 -0
  48. /package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc-sources.jar.md5 → 15.0.8/expo.modules.securestore-15.0.8-sources.jar.md5} +0 -0
  49. /package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc-sources.jar.sha1 → 15.0.8/expo.modules.securestore-15.0.8-sources.jar.sha1} +0 -0
  50. /package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc-sources.jar.sha256 → 15.0.8/expo.modules.securestore-15.0.8-sources.jar.sha256} +0 -0
  51. /package/local-maven-repo/host/exp/exponent/expo.modules.securestore/{15.0.8-canary-20251120-e46b3cc/expo.modules.securestore-15.0.8-canary-20251120-e46b3cc-sources.jar.sha512 → 15.0.8/expo.modules.securestore-15.0.8-sources.jar.sha512} +0 -0
package/CHANGELOG.md CHANGED
@@ -10,7 +10,9 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- - [iOS] Remove byte limit warning. ([#40187](https://github.com/expo/expo/pull/40187) by [@alanjhughes](https://github.com/alanjhughes))
13
+ ## 15.0.8 2025-12-05
14
+
15
+ _This version does not introduce any user-facing changes._
14
16
 
15
17
  ## 15.0.7 — 2025-09-11
16
18
 
@@ -4,16 +4,16 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '15.0.8-canary-20251120-e46b3cc'
7
+ version = '15.0.8'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.securestore"
11
11
  defaultConfig {
12
12
  versionCode 17
13
- versionName '15.0.8-canary-20251120-e46b3cc'
13
+ versionName '15.0.8'
14
14
  }
15
15
  }
16
16
 
17
17
  dependencies {
18
- implementation "androidx.biometric:biometric:1.1.0"
18
+ api "androidx.biometric:biometric:1.1.0"
19
19
  }
@@ -59,7 +59,6 @@ export type SecureStoreOptions = {
59
59
  * Warning: This option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription.
60
60
  * In release builds or when using continuous native generation, make sure to use the `expo-secure-store` config plugin.
61
61
  *
62
- * > **Note:** This library requires a real device for testing since emulators/simulators do not require biometric authentication when retrieving secrets, unlike real iOS devices.
63
62
  */
64
63
  requireAuthentication?: boolean;
65
64
  /**
@@ -115,7 +114,7 @@ export declare function getItemAsync(key: string, options?: SecureStoreOptions):
115
114
  * Stores a key–value pair.
116
115
  *
117
116
  * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.
118
- * @param value The value to store.
117
+ * @param value The value to store. Size limit is 2048 bytes.
119
118
  * @param options An [`SecureStoreOptions`](#securestoreoptions) object.
120
119
  *
121
120
  * @return A promise that rejects if value cannot be stored on the device.
@@ -126,7 +125,7 @@ export declare function setItemAsync(key: string, value: string, options?: Secur
126
125
  * > **Note:** This function blocks the JavaScript thread, so the application may not be interactive when the `requireAuthentication` option is set to `true` until the user authenticates.
127
126
  *
128
127
  * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.
129
- * @param value The value to store.
128
+ * @param value The value to store. Size limit is 2048 bytes.
130
129
  * @param options An [`SecureStoreOptions`](#securestoreoptions) object.
131
130
  *
132
131
  */
@@ -1 +1 @@
1
- {"version":3,"file":"SecureStore.d.ts","sourceRoot":"","sources":["../src/SecureStore.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,6BAA6B,GAAG,MAAM,CAAC;AAGnD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,6BAAkE,CAAC;AAGpG;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,6BACG,CAAC;AAGtD;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,6BAAsD,CAAC;AAG5E;;;GAGG;AACH,eAAO,MAAM,kCAAkC,EAAE,6BACG,CAAC;AAGrD;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,6BACG,CAAC;AAG1C;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,6BAA6D,CAAC;AAG1F;;;GAGG;AACH,eAAO,MAAM,8BAA8B,EAAE,6BACG,CAAC;AAGjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,6BAA6B,CAAC;IAEnD;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF;;;;;;GAMG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAEzD;AAGD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAIf;AAGD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAGD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,IAAI,CAS1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,GAAG,IAAI,CAGpF;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAEvD"}
1
+ {"version":3,"file":"SecureStore.d.ts","sourceRoot":"","sources":["../src/SecureStore.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,6BAA6B,GAAG,MAAM,CAAC;AAGnD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,6BAAkE,CAAC;AAGpG;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,6BACG,CAAC;AAGtD;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,6BAAsD,CAAC;AAG5E;;;GAGG;AACH,eAAO,MAAM,kCAAkC,EAAE,6BACG,CAAC;AAGrD;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,6BACG,CAAC;AAG1C;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,6BAA6D,CAAC;AAG1F;;;GAGG;AACH,eAAO,MAAM,8BAA8B,EAAE,6BACG,CAAC;AAGjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,6BAA6B,CAAC;IAEnD;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF;;;;;;GAMG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAEzD;AAGD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAIf;AAGD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAGD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,IAAI,CAS1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,GAAG,IAAI,CAGpF;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAEvD"}
@@ -1,4 +1,5 @@
1
1
  import ExpoSecureStore from './ExpoSecureStore';
2
+ import { byteCountOverLimit, VALUE_BYTES_LIMIT } from './byteCounter';
2
3
  // @needsAudit
3
4
  /**
4
5
  * The data in the keychain item cannot be accessed after a restart until the device has been
@@ -91,7 +92,7 @@ export async function getItemAsync(key, options = {}) {
91
92
  * Stores a key–value pair.
92
93
  *
93
94
  * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.
94
- * @param value The value to store.
95
+ * @param value The value to store. Size limit is 2048 bytes.
95
96
  * @param options An [`SecureStoreOptions`](#securestoreoptions) object.
96
97
  *
97
98
  * @return A promise that rejects if value cannot be stored on the device.
@@ -108,7 +109,7 @@ export async function setItemAsync(key, value, options = {}) {
108
109
  * > **Note:** This function blocks the JavaScript thread, so the application may not be interactive when the `requireAuthentication` option is set to `true` until the user authenticates.
109
110
  *
110
111
  * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.
111
- * @param value The value to store.
112
+ * @param value The value to store. Size limit is 2048 bytes.
112
113
  * @param options An [`SecureStoreOptions`](#securestoreoptions) object.
113
114
  *
114
115
  */
@@ -151,6 +152,12 @@ function isValidKey(key) {
151
152
  return typeof key === 'string' && /^[\w.-]+$/.test(key);
152
153
  }
153
154
  function isValidValue(value) {
154
- return typeof value === 'string';
155
+ if (typeof value !== 'string') {
156
+ return false;
157
+ }
158
+ if (byteCountOverLimit(value, VALUE_BYTES_LIMIT)) {
159
+ console.warn(`Value being stored in SecureStore is larger than ${VALUE_BYTES_LIMIT} bytes and it may not be stored successfully. In a future SDK version, this call may throw an error.`);
160
+ }
161
+ return true;
155
162
  }
156
163
  //# sourceMappingURL=SecureStore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SecureStore.js","sourceRoot":"","sources":["../src/SecureStore.ts"],"names":[],"mappings":"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","sourcesContent":["import 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 *\n * @deprecated Use an accessibility level that provides some user protection, such as `AFTER_FIRST_UNLOCK`.\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 *\n * @deprecated Use an accessibility level that provides some user protection, such as `AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY`.\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\n// @needsAudit\nexport type SecureStoreOptions = {\n /**\n * - Android: Equivalent of the public/private key pair `Alias`.\n * - iOS: The item's service, equivalent to [`kSecAttrService`](https://developer.apple.com/documentation/security/ksecattrservice/).\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 * Option responsible for enabling the usage of the user authentication methods available on the device while\n * accessing data stored in SecureStore.\n * - Android: Equivalent to [`setUserAuthenticationRequired(true)`](https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean))\n * (requires API 23).\n * - iOS: Equivalent to [`biometryCurrentSet`](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags/2937192-biometrycurrentset).\n * Complete functionality is unlocked only with a freshly generated key - this would not work in tandem with the `keychainService`\n * value used for the others non-authenticated operations.\n *\n * This option works slightly differently across platforms: On Android, user authentication is required for all operations.\n * On iOS, the user is prompted to authenticate only when reading or updating an existing value (not when creating a new one).\n *\n * Warning: This option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription.\n * In release builds or when using continuous native generation, make sure to use the `expo-secure-store` config plugin.\n *\n * > **Note:** This library requires a real device for testing since emulators/simulators do not require biometric authentication when retrieving secrets, unlike real iOS devices.\n */\n requireAuthentication?: boolean;\n /**\n * Custom message displayed to the user while `requireAuthentication` option is turned on.\n */\n authenticationPrompt?: string;\n /**\n * Specifies when the stored entry is accessible, using iOS's `kSecAttrAccessible` property.\n * @see Apple's documentation on [keychain item accessibility](https://developer.apple.com/documentation/security/ksecattraccessible/).\n * @default SecureStore.WHEN_UNLOCKED\n * @platform ios\n */\n keychainAccessible?: KeychainAccessibilityConstant;\n\n /**\n * Specifies the access group the stored entry belongs to.\n * @see Apple's documentation on [Sharing access to keychain items among a collection of apps](https://developer.apple.com/documentation/security/sharing-access-to-keychain-items-among-a-collection-of-apps).\n * @platform ios\n */\n accessGroup?: string;\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 with a `boolean`, indicating whether the SecureStore API is available\n * on the current device. Currently, this resolves `true` on Android and iOS 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 rejects if the value can't be deleted.\n */\nexport async function deleteItemAsync(\n key: string,\n options: SecureStoreOptions = {}\n): Promise<void> {\n ensureValidKey(key);\n\n await ExpoSecureStore.deleteValueWithKeyAsync(key, options);\n}\n\n// @needsAudit\n/**\n * Reads 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. It resolves with `null` if there is no entry\n * for the given key or if the key has been invalidated. It rejects if an error occurs while retrieving the value.\n *\n * > Keys are invalidated by the system when biometrics change, such as adding a new fingerprint or changing the face profile used for face recognition.\n * > After a key has been invalidated, it becomes impossible to read its value.\n * > This only applies to values stored with `requireAuthentication` set to `true`.\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 * Stores a key–value pair.\n *\n * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.\n * @param value The value to store.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n * @return A promise that rejects 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\n await ExpoSecureStore.setValueWithKeyAsync(value, key, options);\n}\n\n/**\n * Stores a key–value pair synchronously.\n * > **Note:** This function blocks the JavaScript thread, so the application may not be interactive when the `requireAuthentication` option is set to `true` until the user authenticates.\n *\n * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.\n * @param value The value to store.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n */\nexport function setItem(key: string, value: string, options: SecureStoreOptions = {}): 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\n return ExpoSecureStore.setValueWithKeySync(value, key, options);\n}\n\n/**\n * Synchronously reads the stored value associated with the provided key.\n * > **Note:** This function blocks the JavaScript thread, so the application may not be interactive when reading a value with `requireAuthentication`\n * > option set to `true` until the user authenticates.\n * @param key The key that was used to store the associated value.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n * @return Previously stored value. It resolves with `null` if there is no entry\n * for the given key or if the key has been invalidated.\n */\nexport function getItem(key: string, options: SecureStoreOptions = {}): string | null {\n ensureValidKey(key);\n return ExpoSecureStore.getValueWithKeySync(key, options);\n}\n\n/**\n * Checks if the value can be saved with `requireAuthentication` option enabled.\n * @return `true` if the device supports biometric authentication and the enrolled method is sufficiently secure. Otherwise, returns `false`. Always returns false on tvOS.\n * @platform android\n * @platform ios\n */\nexport function canUseBiometricAuthentication(): boolean {\n return ExpoSecureStore.canUseBiometricAuthentication();\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 return typeof value === 'string';\n}\n"]}
1
+ {"version":3,"file":"SecureStore.js","sourceRoot":"","sources":["../src/SecureStore.ts"],"names":[],"mappings":"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","sourcesContent":["import ExpoSecureStore from './ExpoSecureStore';\nimport { byteCountOverLimit, VALUE_BYTES_LIMIT } from './byteCounter';\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 *\n * @deprecated Use an accessibility level that provides some user protection, such as `AFTER_FIRST_UNLOCK`.\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 *\n * @deprecated Use an accessibility level that provides some user protection, such as `AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY`.\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\n// @needsAudit\nexport type SecureStoreOptions = {\n /**\n * - Android: Equivalent of the public/private key pair `Alias`.\n * - iOS: The item's service, equivalent to [`kSecAttrService`](https://developer.apple.com/documentation/security/ksecattrservice/).\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 * Option responsible for enabling the usage of the user authentication methods available on the device while\n * accessing data stored in SecureStore.\n * - Android: Equivalent to [`setUserAuthenticationRequired(true)`](https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean))\n * (requires API 23).\n * - iOS: Equivalent to [`biometryCurrentSet`](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags/2937192-biometrycurrentset).\n * Complete functionality is unlocked only with a freshly generated key - this would not work in tandem with the `keychainService`\n * value used for the others non-authenticated operations.\n *\n * This option works slightly differently across platforms: On Android, user authentication is required for all operations.\n * On iOS, the user is prompted to authenticate only when reading or updating an existing value (not when creating a new one).\n *\n * Warning: This option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription.\n * In release builds or when using continuous native generation, make sure to use the `expo-secure-store` config plugin.\n *\n */\n requireAuthentication?: boolean;\n /**\n * Custom message displayed to the user while `requireAuthentication` option is turned on.\n */\n authenticationPrompt?: string;\n /**\n * Specifies when the stored entry is accessible, using iOS's `kSecAttrAccessible` property.\n * @see Apple's documentation on [keychain item accessibility](https://developer.apple.com/documentation/security/ksecattraccessible/).\n * @default SecureStore.WHEN_UNLOCKED\n * @platform ios\n */\n keychainAccessible?: KeychainAccessibilityConstant;\n\n /**\n * Specifies the access group the stored entry belongs to.\n * @see Apple's documentation on [Sharing access to keychain items among a collection of apps](https://developer.apple.com/documentation/security/sharing-access-to-keychain-items-among-a-collection-of-apps).\n * @platform ios\n */\n accessGroup?: string;\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 with a `boolean`, indicating whether the SecureStore API is available\n * on the current device. Currently, this resolves `true` on Android and iOS 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 rejects if the value can't be deleted.\n */\nexport async function deleteItemAsync(\n key: string,\n options: SecureStoreOptions = {}\n): Promise<void> {\n ensureValidKey(key);\n\n await ExpoSecureStore.deleteValueWithKeyAsync(key, options);\n}\n\n// @needsAudit\n/**\n * Reads 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. It resolves with `null` if there is no entry\n * for the given key or if the key has been invalidated. It rejects if an error occurs while retrieving the value.\n *\n * > Keys are invalidated by the system when biometrics change, such as adding a new fingerprint or changing the face profile used for face recognition.\n * > After a key has been invalidated, it becomes impossible to read its value.\n * > This only applies to values stored with `requireAuthentication` set to `true`.\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 * Stores a key–value pair.\n *\n * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, 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 rejects 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\n await ExpoSecureStore.setValueWithKeyAsync(value, key, options);\n}\n\n/**\n * Stores a key–value pair synchronously.\n * > **Note:** This function blocks the JavaScript thread, so the application may not be interactive when the `requireAuthentication` option is set to `true` until the user authenticates.\n *\n * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.\n * @param value The value to store. Size limit is 2048 bytes.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n */\nexport function setItem(key: string, value: string, options: SecureStoreOptions = {}): 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\n return ExpoSecureStore.setValueWithKeySync(value, key, options);\n}\n\n/**\n * Synchronously reads the stored value associated with the provided key.\n * > **Note:** This function blocks the JavaScript thread, so the application may not be interactive when reading a value with `requireAuthentication`\n * > option set to `true` until the user authenticates.\n * @param key The key that was used to store the associated value.\n * @param options An [`SecureStoreOptions`](#securestoreoptions) object.\n *\n * @return Previously stored value. It resolves with `null` if there is no entry\n * for the given key or if the key has been invalidated.\n */\nexport function getItem(key: string, options: SecureStoreOptions = {}): string | null {\n ensureValidKey(key);\n return ExpoSecureStore.getValueWithKeySync(key, options);\n}\n\n/**\n * Checks if the value can be saved with `requireAuthentication` option enabled.\n * @return `true` if the device supports biometric authentication and the enrolled method is sufficiently secure. Otherwise, returns `false`. Always returns false on tvOS.\n * @platform android\n * @platform ios\n */\nexport function canUseBiometricAuthentication(): boolean {\n return ExpoSecureStore.canUseBiometricAuthentication();\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 (byteCountOverLimit(value, VALUE_BYTES_LIMIT)) {\n console.warn(\n `Value being stored in SecureStore is larger than ${VALUE_BYTES_LIMIT} bytes and it may not be stored successfully. In a future SDK version, this call may throw an error.`\n );\n }\n return true;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const VALUE_BYTES_LIMIT = 2048;
2
+ export declare function byteCountOverLimit(value: string, limit: number): boolean;
3
+ //# sourceMappingURL=byteCounter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byteCounter.d.ts","sourceRoot":"","sources":["../src/byteCounter.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAItC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA6BxE"}
@@ -0,0 +1,29 @@
1
+ export const VALUE_BYTES_LIMIT = 2048;
2
+ // note this probably could be JS-engine dependent
3
+ // inspired by https://stackoverflow.com/a/39488643
4
+ export function byteCountOverLimit(value, limit) {
5
+ let bytes = 0;
6
+ for (let i = 0; i < value.length; i++) {
7
+ const codePoint = value.charCodeAt(i);
8
+ // Lone surrogates cannot be passed to encodeURI
9
+ if (codePoint >= 0xd800 && codePoint < 0xe000) {
10
+ if (codePoint < 0xdc00 && i + 1 < value.length) {
11
+ const next = value.charCodeAt(i + 1);
12
+ if (next >= 0xdc00 && next < 0xe000) {
13
+ bytes += 4;
14
+ if (bytes > limit) {
15
+ return true;
16
+ }
17
+ i++;
18
+ continue;
19
+ }
20
+ }
21
+ }
22
+ bytes += codePoint < 0x80 ? 1 : codePoint < 0x800 ? 2 : 3;
23
+ if (bytes > limit) {
24
+ return true;
25
+ }
26
+ }
27
+ return bytes > limit;
28
+ }
29
+ //# sourceMappingURL=byteCounter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byteCounter.js","sourceRoot":"","sources":["../src/byteCounter.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAEtC,kDAAkD;AAClD,mDAAmD;AACnD,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,KAAa;IAC7D,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAEtC,gDAAgD;QAChD,IAAI,SAAS,IAAI,MAAM,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC;YAC9C,IAAI,SAAS,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAErC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;oBACpC,KAAK,IAAI,CAAC,CAAC;oBACX,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;wBAClB,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,CAAC,EAAE,CAAC;oBACJ,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,IAAI,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,GAAG,KAAK,CAAC;AACvB,CAAC","sourcesContent":["export const VALUE_BYTES_LIMIT = 2048;\n\n// note this probably could be JS-engine dependent\n// inspired by https://stackoverflow.com/a/39488643\nexport function byteCountOverLimit(value: string, limit: number): boolean {\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 if (bytes > limit) {\n return true;\n }\n i++;\n continue;\n }\n }\n }\n\n bytes += codePoint < 0x80 ? 1 : codePoint < 0x800 ? 2 : 3;\n if (bytes > limit) {\n return true;\n }\n }\n\n return bytes > limit;\n}\n"]}
@@ -8,7 +8,7 @@
8
8
  "publication": {
9
9
  "groupId": "host.exp.exponent",
10
10
  "artifactId": "expo.modules.securestore",
11
- "version": "15.0.8-canary-20251120-e46b3cc",
11
+ "version": "15.0.8",
12
12
  "repository": "local-maven-repo"
13
13
  }
14
14
  }
@@ -0,0 +1 @@
1
+ c2c1b256a2124c314b2036cf0525c7ebb79a452ba4b8f29fa5189acf30844a45
@@ -0,0 +1 @@
1
+ 2dffed2dc601b8199014aba21fbde87ef37099d57ebd3d05d4e6374f301e3e252837e999895d8fcac837a8364fafa4c467dcc92ba2bec91a07ff08ab031a521f
@@ -3,14 +3,14 @@
3
3
  "component": {
4
4
  "group": "host.exp.exponent",
5
5
  "module": "expo.modules.securestore",
6
- "version": "15.0.8-canary-20251120-e46b3cc",
6
+ "version": "15.0.8",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
10
10
  },
11
11
  "createdBy": {
12
12
  "gradle": {
13
- "version": "9.0.0"
13
+ "version": "8.14.3"
14
14
  }
15
15
  },
16
16
  "variants": [
@@ -22,15 +22,24 @@
22
22
  "org.gradle.libraryelements": "aar",
23
23
  "org.gradle.usage": "java-api"
24
24
  },
25
+ "dependencies": [
26
+ {
27
+ "group": "androidx.biometric",
28
+ "module": "biometric",
29
+ "version": {
30
+ "requires": "1.1.0"
31
+ }
32
+ }
33
+ ],
25
34
  "files": [
26
35
  {
27
- "name": "expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar",
28
- "url": "expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar",
29
- "size": 76113,
30
- "sha512": "5a0407c4499ff5bcdf964be82c67181ad55b2a5e2ce06ebbb1f1ac062ef23fcde3349089c5340d91e092f15f05a7cb36e3c073e3f239384978533df0ff0e48b7",
31
- "sha256": "611eaa630af23a65b0f358a2c15ab1757506468093493f246bc3f16bba7f833c",
32
- "sha1": "52167297cf17ade75a0a680ec1b2d4dcd3af08c7",
33
- "md5": "9815e148666981babbb08036a67eede7"
36
+ "name": "expo.modules.securestore-15.0.8.aar",
37
+ "url": "expo.modules.securestore-15.0.8.aar",
38
+ "size": 76115,
39
+ "sha512": "2dffed2dc601b8199014aba21fbde87ef37099d57ebd3d05d4e6374f301e3e252837e999895d8fcac837a8364fafa4c467dcc92ba2bec91a07ff08ab031a521f",
40
+ "sha256": "c2c1b256a2124c314b2036cf0525c7ebb79a452ba4b8f29fa5189acf30844a45",
41
+ "sha1": "e718b4158b2c9bade4ee03c5402e14f8111ff74e",
42
+ "md5": "5878bd39148e0d832aae804e7a9fde46"
34
43
  }
35
44
  ]
36
45
  },
@@ -60,13 +69,13 @@
60
69
  ],
61
70
  "files": [
62
71
  {
63
- "name": "expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar",
64
- "url": "expo.modules.securestore-15.0.8-canary-20251120-e46b3cc.aar",
65
- "size": 76113,
66
- "sha512": "5a0407c4499ff5bcdf964be82c67181ad55b2a5e2ce06ebbb1f1ac062ef23fcde3349089c5340d91e092f15f05a7cb36e3c073e3f239384978533df0ff0e48b7",
67
- "sha256": "611eaa630af23a65b0f358a2c15ab1757506468093493f246bc3f16bba7f833c",
68
- "sha1": "52167297cf17ade75a0a680ec1b2d4dcd3af08c7",
69
- "md5": "9815e148666981babbb08036a67eede7"
72
+ "name": "expo.modules.securestore-15.0.8.aar",
73
+ "url": "expo.modules.securestore-15.0.8.aar",
74
+ "size": 76115,
75
+ "sha512": "2dffed2dc601b8199014aba21fbde87ef37099d57ebd3d05d4e6374f301e3e252837e999895d8fcac837a8364fafa4c467dcc92ba2bec91a07ff08ab031a521f",
76
+ "sha256": "c2c1b256a2124c314b2036cf0525c7ebb79a452ba4b8f29fa5189acf30844a45",
77
+ "sha1": "e718b4158b2c9bade4ee03c5402e14f8111ff74e",
78
+ "md5": "5878bd39148e0d832aae804e7a9fde46"
70
79
  }
71
80
  ]
72
81
  },
@@ -80,8 +89,8 @@
80
89
  },
81
90
  "files": [
82
91
  {
83
- "name": "expo.modules.securestore-15.0.8-canary-20251120-e46b3cc-sources.jar",
84
- "url": "expo.modules.securestore-15.0.8-canary-20251120-e46b3cc-sources.jar",
92
+ "name": "expo.modules.securestore-15.0.8-sources.jar",
93
+ "url": "expo.modules.securestore-15.0.8-sources.jar",
85
94
  "size": 13495,
86
95
  "sha512": "12ce03192b17ad81fdf2e14ea2a78bb7e932ed68c9619c6ac21f5a07077a3a4d10b558fe74d8ea889f1a736e8493c670cc3c8f86923af310bf2b93a1448b9664",
87
96
  "sha256": "35e759455fb0fd6f3145840ca440d99cc3fd1a0d7ef9d418019a35000b837701",
@@ -0,0 +1 @@
1
+ bd01ff0dcbe827edcb72017562680e310d22b38c7ebf9efd9ca56426e64f229c
@@ -0,0 +1 @@
1
+ ff50ea19ebd0e345f44c7e57543e887784c70eddd7061b910f0747f9e45d85b87019d69b3bf2499ecfa246b1c502a8ea86bf661f8068a536ddf923a8cbbd7f7d
@@ -9,7 +9,7 @@
9
9
  <modelVersion>4.0.0</modelVersion>
10
10
  <groupId>host.exp.exponent</groupId>
11
11
  <artifactId>expo.modules.securestore</artifactId>
12
- <version>15.0.8-canary-20251120-e46b3cc</version>
12
+ <version>15.0.8</version>
13
13
  <packaging>aar</packaging>
14
14
  <name>expo.modules.securestore</name>
15
15
  <url>https://github.com/expo/expo</url>
@@ -25,16 +25,16 @@
25
25
  <url>https://github.com/expo/expo</url>
26
26
  </scm>
27
27
  <dependencies>
28
- <dependency>
29
- <groupId>org.jetbrains.kotlin</groupId>
30
- <artifactId>kotlin-stdlib-jdk7</artifactId>
31
- <version>2.1.20</version>
32
- <scope>runtime</scope>
33
- </dependency>
34
28
  <dependency>
35
29
  <groupId>androidx.biometric</groupId>
36
30
  <artifactId>biometric</artifactId>
37
31
  <version>1.1.0</version>
32
+ <scope>compile</scope>
33
+ </dependency>
34
+ <dependency>
35
+ <groupId>org.jetbrains.kotlin</groupId>
36
+ <artifactId>kotlin-stdlib-jdk7</artifactId>
37
+ <version>2.1.20</version>
38
38
  <scope>runtime</scope>
39
39
  </dependency>
40
40
  </dependencies>
@@ -0,0 +1 @@
1
+ ae2fbc8ad8a3d9c83688e4d4383e72b12abf4b116a609e3a18140f4df83d371b
@@ -0,0 +1 @@
1
+ 090e6ba798a45ed9c5e69a8c6d5ab0d465684836718320fb078f7e2429d3d582eae12a9783f4a8b6e8609698c7785acebe5ee7edd75f892a037a071a1819e5f4
@@ -3,11 +3,11 @@
3
3
  <groupId>host.exp.exponent</groupId>
4
4
  <artifactId>expo.modules.securestore</artifactId>
5
5
  <versioning>
6
- <latest>15.0.8-canary-20251120-e46b3cc</latest>
7
- <release>15.0.8-canary-20251120-e46b3cc</release>
6
+ <latest>15.0.8</latest>
7
+ <release>15.0.8</release>
8
8
  <versions>
9
- <version>15.0.8-canary-20251120-e46b3cc</version>
9
+ <version>15.0.8</version>
10
10
  </versions>
11
- <lastUpdated>20251120092106</lastUpdated>
11
+ <lastUpdated>20251205064545</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 8f6fe0fc22ef24d19a9483dae50d189a
1
+ f4be937465441e2a5e75adfeac4ed674
@@ -1 +1 @@
1
- 81ab85d138f3b6939dcb3402c50542b84712a957
1
+ 54e7d8b9804cdc7621fdd4d48d4fe355783fd32e
@@ -1 +1 @@
1
- 9fc0d23d04c0d30b035a9d16c8763b57ead1963bcc1f2c838996c87332dc6325
1
+ c6f2432f18cbda15ef35c9eb26708111f633aa6bfd3f8a5e013c1d1fdbd209ec
@@ -1 +1 @@
1
- 8cf7aa117d9aa2cb6c5056f9b11b073c039101c3ae3bce8a6e889aa0882977070653998fdf8233c68b388e2f4b6259c9349a335005e4e0c9abdbe1dee16ab771
1
+ dd003df05afd20f3faa773b56b068a3baa2f3be2250941817eda520bb7326dd6f370029447fbbac22cffb7703fc8545cbc25349945d68cb04aff56da540e80e5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-secure-store",
3
- "version": "15.0.8-canary-20251120-e46b3cc",
3
+ "version": "15.0.8",
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",
@@ -37,9 +37,10 @@
37
37
  },
38
38
  "dependencies": {},
39
39
  "devDependencies": {
40
- "expo-module-scripts": "5.1.0-canary-20251120-e46b3cc"
40
+ "expo-module-scripts": "^5.0.8"
41
41
  },
42
42
  "peerDependencies": {
43
- "expo": "55.0.0-canary-20251120-e46b3cc"
44
- }
43
+ "expo": "*"
44
+ },
45
+ "gitHead": "172a69f5f70c1d0e043e1532f924de97210cabc3"
45
46
  }
@@ -1,4 +1,5 @@
1
1
  import ExpoSecureStore from './ExpoSecureStore';
2
+ import { byteCountOverLimit, VALUE_BYTES_LIMIT } from './byteCounter';
2
3
 
3
4
  export type KeychainAccessibilityConstant = number;
4
5
 
@@ -81,7 +82,6 @@ export type SecureStoreOptions = {
81
82
  * Warning: This option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription.
82
83
  * In release builds or when using continuous native generation, make sure to use the `expo-secure-store` config plugin.
83
84
  *
84
- * > **Note:** This library requires a real device for testing since emulators/simulators do not require biometric authentication when retrieving secrets, unlike real iOS devices.
85
85
  */
86
86
  requireAuthentication?: boolean;
87
87
  /**
@@ -161,7 +161,7 @@ export async function getItemAsync(
161
161
  * Stores a key–value pair.
162
162
  *
163
163
  * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.
164
- * @param value The value to store.
164
+ * @param value The value to store. Size limit is 2048 bytes.
165
165
  * @param options An [`SecureStoreOptions`](#securestoreoptions) object.
166
166
  *
167
167
  * @return A promise that rejects if value cannot be stored on the device.
@@ -186,7 +186,7 @@ export async function setItemAsync(
186
186
  * > **Note:** This function blocks the JavaScript thread, so the application may not be interactive when the `requireAuthentication` option is set to `true` until the user authenticates.
187
187
  *
188
188
  * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`.
189
- * @param value The value to store.
189
+ * @param value The value to store. Size limit is 2048 bytes.
190
190
  * @param options An [`SecureStoreOptions`](#securestoreoptions) object.
191
191
  *
192
192
  */
@@ -239,5 +239,13 @@ function isValidKey(key: string) {
239
239
  }
240
240
 
241
241
  function isValidValue(value: string) {
242
- return typeof value === 'string';
242
+ if (typeof value !== 'string') {
243
+ return false;
244
+ }
245
+ if (byteCountOverLimit(value, VALUE_BYTES_LIMIT)) {
246
+ console.warn(
247
+ `Value being stored in SecureStore is larger than ${VALUE_BYTES_LIMIT} bytes and it may not be stored successfully. In a future SDK version, this call may throw an error.`
248
+ );
249
+ }
250
+ return true;
243
251
  }
@@ -0,0 +1,34 @@
1
+ export const VALUE_BYTES_LIMIT = 2048;
2
+
3
+ // note this probably could be JS-engine dependent
4
+ // inspired by https://stackoverflow.com/a/39488643
5
+ export function byteCountOverLimit(value: string, limit: number): boolean {
6
+ let bytes = 0;
7
+
8
+ for (let i = 0; i < value.length; i++) {
9
+ const codePoint = value.charCodeAt(i);
10
+
11
+ // Lone surrogates cannot be passed to encodeURI
12
+ if (codePoint >= 0xd800 && codePoint < 0xe000) {
13
+ if (codePoint < 0xdc00 && i + 1 < value.length) {
14
+ const next = value.charCodeAt(i + 1);
15
+
16
+ if (next >= 0xdc00 && next < 0xe000) {
17
+ bytes += 4;
18
+ if (bytes > limit) {
19
+ return true;
20
+ }
21
+ i++;
22
+ continue;
23
+ }
24
+ }
25
+ }
26
+
27
+ bytes += codePoint < 0x80 ? 1 : codePoint < 0x800 ? 2 : 3;
28
+ if (bytes > limit) {
29
+ return true;
30
+ }
31
+ }
32
+
33
+ return bytes > limit;
34
+ }
@@ -1 +0,0 @@
1
- 5a0407c4499ff5bcdf964be82c67181ad55b2a5e2ce06ebbb1f1ac062ef23fcde3349089c5340d91e092f15f05a7cb36e3c073e3f239384978533df0ff0e48b7
@@ -1 +0,0 @@
1
- c26c8ad9b1d4baac216da551baa8390d5046a23ccc8238e5f2c0acaf510e2124dd2966258701604c2dbeecc43fe91b6fabd8655e8bb487abd3e029cd2d3e60b2
@@ -1 +0,0 @@
1
- d76a198e5bd81e03741c3c29788fd42b40b189e0def8f7927d4f4a226f978286980ca0c98be1ac46dc2cc2b4e828d3cdb9333ff8766b2b0bfc224f676e2f81ba