Skip to content

Commit ee9b6bc

Browse files
feat: prepare 0.5.0 release
1 parent 8fb691d commit ee9b6bc

25 files changed

Lines changed: 2082 additions & 1002 deletions
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Bug report
2+
description: Report a reproducible Nitro Storage bug.
3+
title: "[Bug]: "
4+
labels:
5+
- bug
6+
body:
7+
- type: textarea
8+
id: summary
9+
attributes:
10+
label: Summary
11+
description: What happened?
12+
validations:
13+
required: true
14+
- type: textarea
15+
id: repro
16+
attributes:
17+
label: Reproduction
18+
description: Minimal code or repository that reproduces the issue.
19+
render: tsx
20+
validations:
21+
required: true
22+
- type: dropdown
23+
id: scope
24+
attributes:
25+
label: Storage scope
26+
options:
27+
- Memory
28+
- Disk
29+
- Secure
30+
- Web backend
31+
- Biometric
32+
- Packaging/build
33+
validations:
34+
required: true
35+
- type: input
36+
id: versions
37+
attributes:
38+
label: Versions
39+
description: react-native-nitro-storage, react-native, react-native-nitro-modules, Expo if used.
40+
placeholder: "react-native-nitro-storage 0.5.0, RN 0.83.2, Nitro 0.35.4"
41+
validations:
42+
required: true

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
blank_issues_enabled: true

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,7 @@ temp/
117117
*.md
118118
!README.md
119119
!CONTRIBUTING.md
120-
!CHANGELOG.md
120+
!CHANGELOG.md
121+
!SECURITY.md
122+
!docs/
123+
!docs/**/*.md

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ All notable changes to this project are documented in this file.
44

55
The format follows Keep a Changelog and the project adheres to SemVer.
66

7+
## 0.5.0 - 2026-04-18
8+
9+
### Added
10+
11+
- Add secure-storage capability metadata with `storage.getSecurityCapabilities()`.
12+
- Add metadata-only secure key inspection with `storage.getSecureMetadata(key)` and `storage.getAllSecureMetadata()`.
13+
- Add public `SecurityCapabilities` and `SecureStorageMetadata` types.
14+
- Add security policy and focused docs for secure storage, React hooks, and MMKV migration.
15+
16+
### Changed
17+
18+
- Refresh README positioning, badges, platform support, security model, storage-library comparison guidance, and benchmark guidance for npm/GitHub discoverability.
19+
- Tighten README decisioning with an at-a-glance API map, Expo plugin options, bare Android setup, migration paths, and a release checklist.
20+
- Split detailed usage material into focused docs for API reference, React hooks, secure storage, web backends, batch/transaction/migration workflows, recipes, MMKV migration, and benchmarks.
21+
- Expand npm package description and keywords around React Native secure storage, biometric storage, Keychain, Android Keystore, Nitro Modules, MMKV migration, Expo SecureStore, Zustand/Jotai, and IndexedDB.
22+
- Update release tooling patches for `@swc/core`, `@types/node`, and `turbo`.
23+
724
## 0.4.5 - 2026-04-14
825

926
### Added

README.md

Lines changed: 235 additions & 960 deletions
Large diffs are not rendered by default.

SECURITY.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Security Policy
2+
3+
## Supported Versions
4+
5+
Security fixes are shipped for the latest published `0.x` release line.
6+
7+
| Version | Supported |
8+
| ------- | --------- |
9+
| `0.5.x` | Yes |
10+
| `<0.5` | No |
11+
12+
## Reporting a Vulnerability
13+
14+
Report security issues through GitHub Security Advisories with:
15+
16+
- affected package version
17+
- platform and OS version
18+
- React Native and `react-native-nitro-modules` versions
19+
- reproduction steps
20+
- whether the issue affects Memory, Disk, Secure, biometric storage, web backends, or packaging
21+
22+
Do not publish proof-of-concept exploit details until a fix is available.
23+
24+
## Storage Boundary
25+
26+
Native Secure scope delegates encryption to platform storage APIs: iOS Keychain and Android Jetpack Security `EncryptedSharedPreferences`. Web Secure scope is API-compatible but defaults to namespaced `localStorage`; use a custom web secure backend when browser-side storage must meet a stricter threat model.

apps/example/app/index.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ export default function HomeScreen() {
164164
const [token, setToken] = useStorage(secureTokenItem);
165165
const [tempToken, setTempToken] = useState("");
166166
const tempTokenRef = useRef("");
167+
const [secureMetadata, setSecureMetadata] = useState(() =>
168+
storage.getSecureMetadata("secure-token"),
169+
);
170+
const [secureMetadataCount, setSecureMetadataCount] = useState(
171+
() => storage.getAllSecureMetadata().length,
172+
);
167173

168174
// 4. Namespaces
169175
const [nsPref, setNsPref] = useStorage(namespacedItem);
@@ -234,6 +240,12 @@ export default function HomeScreen() {
234240
const [diskBufferedPreview, setDiskBufferedPreview] = useState("(empty)");
235241
const [classifiedErrorCode, setClassifiedErrorCode] = useState("(none)");
236242
const capabilities = storage.getCapabilities();
243+
const securityCapabilities = storage.getSecurityCapabilities();
244+
245+
const refreshSecureMetadata = () => {
246+
setSecureMetadata(storage.getSecureMetadata("secure-token"));
247+
setSecureMetadataCount(storage.getAllSecureMetadata().length);
248+
};
237249

238250
return (
239251
<Page title="Nitro Storage" subtitle="Complete feature showcase">
@@ -356,6 +368,7 @@ export default function HomeScreen() {
356368
setToken(tempTokenRef.current.trim());
357369
tempTokenRef.current = "";
358370
setTempToken("");
371+
refreshSecureMetadata();
359372
}}
360373
variant="success"
361374
style={styles.flex1}
@@ -366,6 +379,7 @@ export default function HomeScreen() {
366379
variant="danger"
367380
onPress={() => {
368381
secureTokenItem.delete();
382+
refreshSecureMetadata();
369383
}}
370384
/>
371385
</View>
@@ -377,6 +391,16 @@ export default function HomeScreen() {
377391
color={Colors.secure}
378392
/>
379393
) : null}
394+
<StatusRow
395+
testID="secure-metadata-kind"
396+
label="Stored as"
397+
value={secureMetadata.kind}
398+
/>
399+
<StatusRow
400+
testID="secure-metadata-count"
401+
label="Secure key inventory"
402+
value={String(secureMetadataCount)}
403+
/>
380404
</Card>
381405

382406
{/* 4. Namespaces */}
@@ -1034,6 +1058,16 @@ export default function HomeScreen() {
10341058
label="Secure backend"
10351059
value={capabilities.backend.secure}
10361060
/>
1061+
<StatusRow
1062+
testID="capabilities-secure-encrypted"
1063+
label="Secure encrypted"
1064+
value={securityCapabilities.secureStorage.encrypted}
1065+
/>
1066+
<StatusRow
1067+
testID="capabilities-biometric-prompt"
1068+
label="Biometric prompt"
1069+
value={securityCapabilities.biometric.prompt}
1070+
/>
10371071
<StatusRow
10381072
testID="capabilities-buffering"
10391073
label="Write buffering"

apps/example/components/smoke-test.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,27 @@ function buildTests(): { label: string; fn: TestFn }[] {
428428
label: "Capabilities / error codes / disk buffering",
429429
fn: () => {
430430
const capabilities = storage.getCapabilities();
431+
const securityCapabilities = storage.getSecurityCapabilities();
431432
assert(capabilities.writeBuffering.disk, "disk buffering unavailable");
432433
assert(
433434
capabilities.errorClassification,
434435
"error classification unavailable",
435436
);
437+
assert(
438+
securityCapabilities.metadata.listsWithoutValues,
439+
"secure metadata inventory unavailable",
440+
);
441+
storage.setString(
442+
"__smoke_secure_meta__",
443+
"secret",
444+
StorageScope.Secure,
445+
);
446+
const secureMetadata = storage.getSecureMetadata(
447+
"__smoke_secure_meta__",
448+
);
449+
assert(secureMetadata.exists, "expected secure metadata exists");
450+
assert(!secureMetadata.valueExposed, "metadata exposed a secret value");
451+
storage.deleteString("__smoke_secure_meta__", StorageScope.Secure);
436452
assert(
437453
getStorageErrorCode(
438454
new Error(

0 commit comments

Comments
 (0)