|
2 | 2 |
|
3 | 3 | Each chapter from the migration checklist includes granular tasks below. Pick tasks independently to parallelize work. |
4 | 4 |
|
| 5 | +> **Note**: This document uses standard Markdown `<details>` and `<summary>` tags for collapsible task sections, ensuring proper rendering on GitHub and other Markdown viewers. |
| 6 | +
|
5 | 7 | ## 1. Scanning adapters & NFC lifecycle |
6 | 8 |
|
7 | | -:::task-stub{title="Create scanning adapter interface"} |
| 9 | +<details> |
| 10 | +<summary><strong>Create scanning adapter interface</strong></summary> |
8 | 11 |
|
9 | 12 | 1. In `src/adapters/`, add `scanner.ts` exporting TypeScript interfaces for `MRZScanner` and `NFCScanner`. |
10 | 13 | 2. Reference React Native camera/NFC packages only through these interfaces. |
11 | | -3. Document usage in `README.md`. |
12 | | - ::: |
| 14 | +3. Document usage in `README.md`. Include a "Privacy & PII" subsection: forbid logging MRZ/NFC data, enable on-device processing only, and provide redaction utilities for debug. |
| 15 | +4. Never log MRZ strings, NFC APDUs, or chip contents anywhere (including telemetry). |
| 16 | +5. Ensure camera frames and NFC/APDU processing occur on-device with analytics disabled for those paths by default. |
| 17 | +6. Provide a redact/sanitize helper function for debug builds only. |
| 18 | + |
| 19 | +</details> |
13 | 20 |
|
14 | | -:::task-stub{title="Implement React Native MRZ adapter"} |
| 21 | +<details> |
| 22 | +<summary><strong>Implement React Native MRZ adapter</strong></summary> |
15 | 23 |
|
16 | 24 | 1. Add `mrz-rn.ts` in `src/adapters/` implementing `MRZScanner` via `react-native-vision-camera`. |
17 | 25 | 2. Expose configuration for permissions, preview, and result handling. |
18 | 26 | 3. Write unit tests under `tests/` mocking camera output. |
19 | | - ::: |
20 | 27 |
|
21 | | -:::task-stub{title="Implement React Native NFC adapter"} |
| 28 | +</details> |
| 29 | + |
| 30 | +<details> |
| 31 | +<summary><strong>Implement React Native NFC adapter</strong></summary> |
22 | 32 |
|
23 | 33 | 1. Create `nfc-rn.ts` in `src/adapters/` implementing `NFCScanner` with `react-native-nfc-manager`. |
24 | 34 | 2. Provide lifecycle hooks so the app can call `keepScreenOn(true|false)` during sessions. |
25 | 35 | 3. Document app-level setup in `MIGRATION_CHECKLIST.md`. |
26 | | - ::: |
27 | 36 |
|
28 | | -:::task-stub{title="Add scanning sample"} |
| 37 | +</details> |
| 38 | + |
| 39 | +<details> |
| 40 | +<summary><strong>Add scanning sample</strong></summary> |
29 | 41 |
|
30 | 42 | 1. Under `samples/`, add a React Native demo showing MRZ then NFC scanning. |
31 | 43 | 2. Include simple error handling and log output. |
32 | 44 | 3. Reference the sample from `README.md`. |
33 | | - ::: |
| 45 | + |
| 46 | +</details> |
34 | 47 |
|
35 | 48 | ## 2. Processing helpers (MRZ & NFC) |
36 | 49 |
|
37 | | -:::task-stub{title="Test MRZ parsing utilities"} |
| 50 | +<details> |
| 51 | +<summary><strong>Test MRZ parsing utilities</strong></summary> |
38 | 52 |
|
39 | 53 | 1. In `tests/processing/`, add test cases for `extractMRZInfo` and `formatDateToYYMMDD` covering valid/invalid inputs. |
40 | 54 | 2. Use sample MRZ strings from ICAO specs for fixtures. |
41 | | - ::: |
42 | 55 |
|
43 | | -:::task-stub{title="Add NFC response parser"} |
| 56 | +</details> |
| 57 | + |
| 58 | +<details> |
| 59 | +<summary><strong>Add NFC response parser</strong></summary> |
44 | 60 |
|
45 | 61 | 1. Create `src/processing/nfc.ts` exporting a pure function to parse NFC chip responses into DG1/DG2 structures. |
46 | 62 | 2. Write tests in `tests/processing/nfc.test.ts`. |
47 | 63 | 3. Ensure no React Native dependencies. |
48 | | - ::: |
49 | 64 |
|
50 | | -:::task-stub{title="Expose processing utilities"} |
| 65 | +</details> |
| 66 | + |
| 67 | +<details> |
| 68 | +<summary><strong>Expose processing utilities</strong></summary> |
51 | 69 |
|
52 | 70 | 1. Update `src/index.ts` to re-export MRZ and NFC helpers. |
53 | | -2. Document them in `README.md` under a “Processing utilities” section. |
54 | | - ::: |
| 71 | +2. Document them in `README.md` under a "Processing utilities" section. |
| 72 | + |
| 73 | +</details> |
55 | 74 |
|
56 | 75 | ## 3. Validation module |
57 | 76 |
|
58 | | -:::task-stub{title="Port minimal document validation"} |
| 77 | +<details> |
| 78 | +<summary><strong>Port minimal document validation</strong></summary> |
59 | 79 |
|
60 | 80 | 1. Create `src/validation/document.ts`. |
61 | 81 | 2. Port `isPassportDataValid` logic without analytics or store calls. |
62 | 82 | 3. Type the function using `PassportData` from `src/types/public.ts`. |
63 | | - ::: |
64 | 83 |
|
65 | | -:::task-stub{title="Test document validation"} |
| 84 | +</details> |
| 85 | + |
| 86 | +<details> |
| 87 | +<summary><strong>Test document validation</strong></summary> |
66 | 88 |
|
67 | 89 | 1. Add `tests/validation/document.test.ts` with cases for missing metadata and hash mismatches. |
68 | 90 | 2. Run via `yarn workspace @selfxyz/mobile-sdk-alpha test`. |
69 | | - ::: |
| 91 | + |
| 92 | +</details> |
70 | 93 |
|
71 | 94 | ## 4. Protocol synchronization |
72 | 95 |
|
73 | | -:::task-stub{title="Add paginated tree fetch"} |
| 96 | +<details> |
| 97 | +<summary><strong>Add paginated tree fetch</strong></summary> |
74 | 98 |
|
75 | 99 | 1. Under `src/client/`, create `treeFetcher.ts` with `fetchTreePaginated(url, pageSize)` returning concatenated pages. |
76 | 100 | 2. Handle pagination tokens from the backend. |
77 | 101 | 3. Include retries for transient network errors. |
78 | | - ::: |
79 | 102 |
|
80 | | -:::task-stub{title="Introduce tree cache with TTL"} |
| 103 | +</details> |
| 104 | + |
| 105 | +<details> |
| 106 | +<summary><strong>Introduce tree cache with TTL</strong></summary> |
81 | 107 |
|
82 | 108 | 1. In `treeFetcher.ts`, wrap results with an in-memory cache keyed by URL and `pageSize`. |
83 | 109 | 2. Allow TTL configuration through SDK options. |
84 | 110 | 3. Expose `clearExpired()` to purge stale entries. |
85 | | - ::: |
86 | 111 |
|
87 | | -:::task-stub{title="Implement root verification"} |
| 112 | +</details> |
| 113 | + |
| 114 | +<details> |
| 115 | +<summary><strong>Implement root verification</strong></summary> |
88 | 116 |
|
89 | 117 | 1. After assembling the full tree, compute its root and compare to the server-provided root. |
90 | 118 | 2. Throw descriptive errors on mismatch. |
91 | 119 | 3. Add tests with mock data ensuring verification triggers. |
92 | | - ::: |
| 120 | + |
| 121 | +</details> |
93 | 122 |
|
94 | 123 | ## 5. Proof input generation |
95 | 124 |
|
96 | | -:::task-stub{title="Port generateTEEInputsRegister"} |
| 125 | +<details> |
| 126 | +<summary><strong>Port generateTEEInputsRegister</strong></summary> |
97 | 127 |
|
98 | 128 | 1. Copy logic from `app/src/utils/proving/provingInputs.ts` lines 106-117 into `src/proving/registerInputs.ts`. |
99 | 129 | 2. Replace `useProtocolStore` calls with parameters for `dscTree` and environment. |
100 | 130 | 3. Ensure types align with `PassportData`. |
101 | | - ::: |
102 | 131 |
|
103 | | -:::task-stub{title="Port generateTEEInputsDisclose"} |
| 132 | +</details> |
| 133 | + |
| 134 | +<details> |
| 135 | +<summary><strong>Port generateTEEInputsDisclose</strong></summary> |
104 | 136 |
|
105 | 137 | 1. Move disclosure-related logic into `src/proving/discloseInputs.ts`. |
106 | 138 | 2. Accept OFAC trees and other dependencies as function parameters instead of store lookups. |
107 | 139 | 3. Write unit tests for both register and disclose generators with mocked trees. |
108 | | - ::: |
| 140 | + |
| 141 | +</details> |
109 | 142 |
|
110 | 143 | ## 6. TEE session management |
111 | 144 |
|
112 | | -:::task-stub{title="Implement TEE WebSocket wrapper"} |
| 145 | +<details> |
| 146 | +<summary><strong>Implement TEE WebSocket wrapper</strong></summary> |
113 | 147 |
|
114 | 148 | 1. Add `src/tee/session.ts` exporting `openSession(url, options)`. |
115 | 149 | 2. Accept an `AbortSignal` and timeout; reject if aborted or timed out. |
116 | 150 | 3. Emit progress events via an `EventEmitter` interface. |
117 | | - ::: |
118 | 151 |
|
119 | | -:::task-stub{title="Test and document TEE session"} |
| 152 | +</details> |
| 153 | + |
| 154 | +<details> |
| 155 | +<summary><strong>Test and document TEE session</strong></summary> |
120 | 156 |
|
121 | 157 | 1. Write tests using a mocked WebSocket server verifying abort/timeout handling. |
122 | 158 | 2. Update `README.md` with example code showing progress listener usage. |
123 | | - ::: |
| 159 | + |
| 160 | +</details> |
124 | 161 |
|
125 | 162 | ## 7. Attestation verification |
126 | 163 |
|
127 | | -:::task-stub{title="Port basic attestation verification"} |
| 164 | +<details> |
| 165 | +<summary><strong>Port basic attestation verification</strong></summary> |
128 | 166 |
|
129 | 167 | 1. In `src/attestation/verify.ts`, port `checkPCR0Mapping` and `getPublicKey` without logging. |
130 | 168 | 2. Replace on-chain contract calls with parameters or pluggable providers. |
131 | 169 | 3. Provide TypeScript types for attestation documents. |
132 | | - ::: |
| 170 | +4. Validate attestation timestamps against device clock with configurable skew tolerance. |
| 171 | +5. Define trust anchors and key pinning strategy for PCR0/public key mapping. |
| 172 | +6. Add optional OCSP/CRL checks with network fallbacks and clear opt-out rationale. |
| 173 | + |
| 174 | +</details> |
133 | 175 |
|
134 | | -:::task-stub{title="Implement certificate chain check"} |
| 176 | +<details> |
| 177 | +<summary><strong>Implement certificate chain check</strong></summary> |
135 | 178 |
|
136 | 179 | 1. Port simplified `verifyCertChain` from `attest.ts` ensuring no Node-specific APIs. |
137 | 180 | 2. Add unit tests with mock certificates to cover success and failure paths. |
138 | | - ::: |
| 181 | + |
| 182 | +</details> |
139 | 183 |
|
140 | 184 | ## 8. Crypto adapters |
141 | 185 |
|
142 | | -:::task-stub{title="Create CryptoAdapter"} |
| 186 | +<details> |
| 187 | +<summary><strong>Create CryptoAdapter</strong></summary> |
143 | 188 |
|
144 | 189 | 1. In `src/crypto/`, add `adapter.ts` defining methods for hashing, random bytes, and asymmetric operations. |
145 | 190 | 2. Document required methods (e.g., `digest`, `getRandomValues`, `subtle` operations). |
146 | | - ::: |
| 191 | +3. Add a constant-time `timingSafeEqual(a, b)` utility and document RNG requirements (cryptographically secure only). |
| 192 | +4. Implement environment detection for WebCrypto (detect globalThis.crypto and feature-check subtle/digest/getRandomValues). |
| 193 | +5. Provide fallback to react-native-get-random-values or noble-based adapter when WebCrypto unavailable. |
| 194 | +6. Ensure all secret comparisons use constant-time comparison instead of ===. |
| 195 | + |
| 196 | +</details> |
147 | 197 |
|
148 | | -:::task-stub{title="Implement crypto adapters"} |
| 198 | +<details> |
| 199 | +<summary><strong>Implement crypto adapters</strong></summary> |
149 | 200 |
|
150 | 201 | 1. Add `webcrypto.ts` implementing the interface using `globalThis.crypto`. |
151 | 202 | 2. Add `noble.ts` using `@noble/hashes` and `@noble/curves` where WebCrypto is unavailable. |
152 | 203 | 3. Export a factory that chooses the appropriate adapter at runtime. |
153 | 204 | 4. Provide tests ensuring both adapters yield identical results for sample inputs. |
154 | | - ::: |
| 205 | +5. In noble adapter: select well-known safe curves (secp256r1/ed25519) and recommended hash algorithms. |
| 206 | +6. Ensure sensitive buffers are zeroized after use where possible. |
| 207 | +7. Add tests for constant-time comparator and RNG fallback behavior. |
| 208 | + |
| 209 | +</details> |
155 | 210 |
|
156 | 211 | ## 9. Artifact management |
157 | 212 |
|
158 | | -:::task-stub{title="Add artifact manifest schema"} |
| 213 | +<details> |
| 214 | +<summary><strong>Add artifact manifest schema</strong></summary> |
159 | 215 |
|
160 | 216 | 1. In `src/artifacts/`, create `manifest.ts` defining the JSON schema (name, version, urls, hashes). |
161 | | -2. Implement a function `verifyManifest(manifest, signature)` that validates hashes and schema. |
162 | | - ::: |
| 217 | +2. Implement `verifyManifest(manifest, signature, publisherKey)` that validates schema and signature using a pinned publisher key. Only then validate per-file hashes. |
| 218 | +3. Verify manifest signature against pinned public key before any caching or storage access. |
| 219 | +4. Enforce CDN/domain allowlist and validate response Content-Length header against expected sizes. |
| 220 | +5. Compute and verify streaming hash while downloading to avoid buffering full files in memory. |
163 | 221 |
|
164 | | -:::task-stub{title="Download and cache artifacts"} |
| 222 | +</details> |
| 223 | + |
| 224 | +<details> |
| 225 | +<summary><strong>Download and cache artifacts</strong></summary> |
165 | 226 |
|
166 | 227 | 1. Create `downloader.ts` that fetches artifact files from a CDN, verifies integrity, and stores them via a pluggable storage adapter. |
167 | 228 | 2. Support cache lookup before network fetch and provide `clearCache()` helper. |
168 | 229 | 3. Add tests mocking fetch and storage layers. |
169 | | - ::: |
| 230 | +4. Stream HTTP responses into hash verifier (do not buffer full files). |
| 231 | +5. Verify Content-Length matches bytes read to detect truncation. |
| 232 | +6. Validate download host against allowed-domains whitelist. |
| 233 | +7. Only write to persistent storage after both signature and per-file hash verification succeed. |
| 234 | + |
| 235 | +</details> |
170 | 236 |
|
171 | 237 | ## 10. Sample applications |
172 | 238 |
|
173 | | -:::task-stub{title="Add React Native sample"} |
| 239 | +<details> |
| 240 | +<summary><strong>Add React Native sample</strong></summary> |
174 | 241 |
|
175 | 242 | 1. Under `samples/react-native/`, scaffold a bare-bones app using Expo or React Native CLI. |
176 | 243 | 2. Demonstrate MRZ scanning, NFC reading, and registration flow using SDK APIs. |
177 | 244 | 3. Include instructions in a `README.md`. |
178 | | - ::: |
179 | 245 |
|
180 | | -:::task-stub{title="Add web sample"} |
| 246 | +</details> |
| 247 | + |
| 248 | +<details> |
| 249 | +<summary><strong>Add web sample</strong></summary> |
181 | 250 |
|
182 | 251 | 1. Under `samples/web/`, set up a Vite/React project showing browser-based MRZ input and proof generation. |
183 | 252 | 2. Document setup and build steps. |
184 | | - ::: |
185 | 253 |
|
186 | | -:::task-stub{title="Configure OpenPassport scheme"} |
| 254 | +</details> |
| 255 | + |
| 256 | +<details> |
| 257 | +<summary><strong>Configure OpenPassport scheme</strong></summary> |
187 | 258 |
|
188 | | -1. In the React Native sample’s iOS project, add URL type `OpenPassport` to `Info.plist`. |
189 | | -2. Document how the scheme is used for callback flows. |
190 | | - ::: |
| 259 | +1. In the React Native sample's iOS project, add URL type `OpenPassport` to `Info.plist`. |
| 260 | +2. Document Android intent filters (AndroidManifest.xml). Ensure scheme uniqueness and validate redirect origins to prevent hijacking. |
| 261 | +3. Choose a scheme unique to your app (e.g., using reverse-domain or app-identifier prefix). |
| 262 | +4. Detect and handle collisions (fallback checks, verify caller package/signature). |
| 263 | +5. Verify redirect domains and consider app-claimed links/Android App Links and iOS Universal Links for stronger security. |
| 264 | + |
| 265 | +</details> |
191 | 266 |
|
192 | 267 | ## 11. Integrate SDK into `/app` |
193 | 268 |
|
194 | | -:::task-stub{title="Integrate SDK in /app"} |
| 269 | +<details> |
| 270 | +<summary><strong>Integrate SDK in /app</strong></summary> |
195 | 271 |
|
196 | 272 | 1. Add `@selfxyz/mobile-sdk-alpha` to `app/package.json`. |
197 | 273 | 2. Replace existing MRZ/NFC scanning modules with SDK adapters. |
198 | 274 | 3. Wire app screens to SDK processing and validation helpers. |
199 | 275 | 4. Validate builds and unit tests in the `app` workspace. |
200 | | - ::: |
| 276 | + |
| 277 | +</details> |
201 | 278 |
|
202 | 279 | ## 12. In-SDK lightweight demo |
203 | 280 |
|
204 | | -:::task-stub{title="Create embedded demo app"} |
| 281 | +<details> |
| 282 | +<summary><strong>Create embedded demo app</strong></summary> |
205 | 283 |
|
206 | 284 | 1. Scaffold `demo/` under the SDK as a minimal React Native project. |
207 | 285 | 2. Use SDK APIs for MRZ → NFC → registration flow. |
208 | 286 | 3. Expose simple theming configuration. |
209 | 287 | 4. Add `demo/README.md` with build/run instructions. |
210 | | - ::: |
| 288 | +5. Add publishing guardrails: exclude `demo/` from npm and add a CI step to verify the published tarball contents. |
| 289 | + |
| 290 | +</details> |
0 commit comments