native-update 1.3.2 → 1.3.4

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.
@@ -0,0 +1,312 @@
1
+ # Testing Requirements
2
+
3
+ This document outlines the testing requirements for the native-update plugin.
4
+
5
+ ## Current Testing Status
6
+
7
+ - **Plugin testing**: Handled in actual/live applications using the plugin
8
+ - **Example apps**: Demonstrate functionality for manual testing
9
+ - **Unit tests (TypeScript)**: ✅ Implemented in `/src/__tests__/`
10
+ - **iOS Native Tests (XCTest)**: ✅ Implemented in `/ios/Tests/NativeUpdateTests/`
11
+ - **Android Native Tests (JUnit/Kotlin)**: ✅ Implemented in `/android/src/test/`
12
+ - **E2E Tests (Detox)**: ✅ Implemented in `/e2e/`
13
+
14
+ ---
15
+
16
+ ## iOS Native Tests (XCTest)
17
+
18
+ ### Test File Structure
19
+ ```
20
+ ios/
21
+ └── Tests/
22
+ └── NativeUpdateTests/
23
+ ├── LiveUpdateTests.swift
24
+ ├── AppUpdateTests.swift
25
+ ├── AppReviewTests.swift
26
+ ├── BundleManagerTests.swift
27
+ └── SecurityTests.swift
28
+ ```
29
+
30
+ ### Test Categories
31
+
32
+ #### LiveUpdateTests.swift
33
+ - `testCheckForUpdate()` - Verify update check returns correct response
34
+ - `testDownloadBundle()` - Verify bundle download with progress
35
+ - `testApplyUpdate()` - Verify bundle extraction and application
36
+ - `testRollback()` - Verify rollback to previous version
37
+ - `testChecksumVerification()` - Verify SHA-256 checksum validation
38
+ - `testSignatureVerification()` - Verify RSA/ECDSA signature validation
39
+ - `testChannelManagement()` - Verify channel switching (production/staging/dev)
40
+
41
+ #### AppUpdateTests.swift
42
+ - `testCheckAppStoreVersion()` - Verify app store version check
43
+ - `testVersionComparison()` - Verify semantic version comparison
44
+ - `testUpdateAvailability()` - Verify update availability detection
45
+ - `testOpenAppStore()` - Verify App Store navigation
46
+
47
+ #### AppReviewTests.swift
48
+ - `testRequestReview()` - Verify StoreKit review request
49
+ - `testRateLimiting()` - Verify review request rate limiting
50
+
51
+ #### BundleManagerTests.swift
52
+ - `testBundleStorage()` - Verify bundle storage in app sandbox
53
+ - `testBundleCleanup()` - Verify old bundle cleanup
54
+ - `testActiveBundlePath()` - Verify active bundle path resolution
55
+
56
+ #### SecurityTests.swift
57
+ - `testInputValidation()` - Verify URL/input sanitization
58
+ - `testHTTPSEnforcement()` - Verify HTTPS-only connections
59
+ - `testDowngradeProtection()` - Verify version downgrade prevention
60
+ - `testKeychain Storage()` - Verify sensitive data in Keychain
61
+
62
+ ### Running iOS Tests
63
+ ```bash
64
+ cd ios
65
+ xcodebuild test -scheme NativeUpdate -destination 'platform=iOS Simulator,name=iPhone 15'
66
+ ```
67
+
68
+ ### Current Test Files (✅ Implemented)
69
+
70
+ | File | Tests | Status |
71
+ |------|-------|--------|
72
+ | `SecurityManagerTests.swift` | 6 tests | ✅ |
73
+ | `LiveUpdateTests.swift` | 10 tests | ✅ |
74
+ | `AppUpdateTests.swift` | 5 tests | ✅ |
75
+ | `AppReviewTests.swift` | 5 tests | ✅ |
76
+ | `BackgroundUpdateTests.swift` | 6 tests | ✅ |
77
+ | **Total** | **32 tests** | ✅ |
78
+
79
+ ---
80
+
81
+ ## Android Native Tests (JUnit)
82
+
83
+ ### Test File Structure
84
+ ```
85
+ android/
86
+ └── src/
87
+ └── test/
88
+ └── java/
89
+ └── com/
90
+ └── aoneahsan/
91
+ └── nativeupdate/
92
+ ├── LiveUpdateTest.kt
93
+ ├── AppUpdateTest.kt
94
+ ├── AppReviewTest.kt
95
+ ├── BundleManagerTest.kt
96
+ └── SecurityTest.kt
97
+ ```
98
+
99
+ ### Test Categories
100
+
101
+ #### LiveUpdateTest.kt
102
+ - `testCheckForUpdate()` - Verify update check HTTP request
103
+ - `testDownloadBundle()` - Verify bundle download with OkHttp
104
+ - `testApplyUpdate()` - Verify bundle extraction to internal storage
105
+ - `testRollback()` - Verify rollback mechanism
106
+ - `testChecksumVerification()` - Verify SHA-256 validation
107
+ - `testSignatureVerification()` - Verify signature with Android Keystore
108
+ - `testChannelManagement()` - Verify channel configuration
109
+
110
+ #### AppUpdateTest.kt
111
+ - `testCheckPlayStoreVersion()` - Verify Play Core version check
112
+ - `testImmediateUpdate()` - Verify blocking update flow
113
+ - `testFlexibleUpdate()` - Verify background update flow
114
+ - `testUpdatePriority()` - Verify update priority handling
115
+
116
+ #### AppReviewTest.kt
117
+ - `testRequestReview()` - Verify Play Core review API
118
+ - `testReviewManagerInitialization()` - Verify ReviewManager setup
119
+ - `testRateLimiting()` - Verify request limiting
120
+
121
+ #### BundleManagerTest.kt
122
+ - `testBundleStorage()` - Verify internal storage operations
123
+ - `testBundleCleanup()` - Verify old bundle deletion
124
+ - `testActiveBundlePath()` - Verify bundle path resolution
125
+ - `testStoragePermissions()` - Verify no external storage access
126
+
127
+ #### SecurityTest.kt
128
+ - `testInputValidation()` - Verify input sanitization
129
+ - `testHTTPSEnforcement()` - Verify HTTPS-only policy
130
+ - `testDowngradeProtection()` - Verify version validation
131
+ - `testKeystore()` - Verify Android Keystore usage
132
+
133
+ ### Running Android Tests
134
+ ```bash
135
+ cd android
136
+ ./gradlew test
137
+ ./gradlew connectedAndroidTest # For instrumented tests
138
+ ```
139
+
140
+ ### Current Test Files (✅ Implemented)
141
+
142
+ | File | Tests | Status |
143
+ |------|-------|--------|
144
+ | `SecurityManagerTest.kt` | 10 tests | ✅ |
145
+ | `LiveUpdatePluginTest.kt` | 10 tests | ✅ |
146
+ | `AppUpdatePluginTest.kt` | 5 tests | ✅ |
147
+ | `AppReviewPluginTest.kt` | 5 tests | ✅ |
148
+ | `BackgroundUpdateWorkerTest.kt` | 5 tests | ✅ |
149
+ | `BackgroundNotificationManagerTest.kt` | 5 tests | ✅ |
150
+ | **Total** | **40 tests** | ✅ |
151
+
152
+ ### Test Dependencies (Added to build.gradle)
153
+
154
+ ```gradle
155
+ testImplementation 'junit:junit:4.13.2'
156
+ testImplementation 'org.mockito:mockito-core:5.8.0'
157
+ testImplementation 'org.mockito.kotlin:mockito-kotlin:5.2.1'
158
+ testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
159
+ testImplementation 'com.google.truth:truth:1.1.5'
160
+ testImplementation 'org.robolectric:robolectric:4.11.1'
161
+ ```
162
+
163
+ ---
164
+
165
+ ## End-to-End Tests (Detox) ✅ IMPLEMENTED
166
+
167
+ The E2E tests are implemented in `/e2e/` using Detox framework.
168
+
169
+ ### Framework
170
+ - **Detox** for React Native + Capacitor apps
171
+
172
+ ### Test Coverage
173
+
174
+ | Spec File | Tests | Status |
175
+ |-----------|-------|--------|
176
+ | `ota-update.e2e.spec.js` | 5 tests | ✅ |
177
+ | `download-progress.e2e.spec.js` | 5 tests | ✅ |
178
+ | `channel-switching.e2e.spec.js` | 5 tests | ✅ |
179
+ | `error-handling.e2e.spec.js` | 4 tests | ✅ |
180
+ | **Total** | **19 tests** | ✅ |
181
+
182
+ ### Running E2E Tests
183
+
184
+ ```bash
185
+ cd e2e
186
+ yarn install
187
+ yarn build:android # or yarn build:ios
188
+ yarn test:android # or yarn test:ios
189
+ ```
190
+
191
+ ### Mock Server
192
+
193
+ Start the mock update server for E2E tests:
194
+ ```bash
195
+ yarn start-mock-server
196
+ ```
197
+
198
+ ### Test Scenarios
199
+
200
+ #### OTA Update Flow
201
+ ```
202
+ 1. App starts with version 1.0.0
203
+ 2. Server has version 1.1.0 available
204
+ 3. App checks for update → receives update info
205
+ 4. App downloads bundle → shows progress
206
+ 5. App applies update → restarts
207
+ 6. App shows version 1.1.0
208
+ ```
209
+
210
+ #### Rollback Flow
211
+ ```
212
+ 1. App has version 1.1.0 applied
213
+ 2. New update 1.2.0 has critical bug
214
+ 3. App applies 1.2.0 → crashes on start
215
+ 4. App automatically rolls back to 1.1.0
216
+ 5. App reports rollback to server
217
+ ```
218
+
219
+ #### Native Update Flow
220
+ ```
221
+ 1. App version 1.0.0 installed from store
222
+ 2. Store has version 2.0.0 (native update required)
223
+ 3. App detects native update available
224
+ 4. User shown update prompt
225
+ 5. User redirected to app store
226
+ ```
227
+
228
+ #### Channel Switching
229
+ ```
230
+ 1. App configured for 'production' channel
231
+ 2. Developer switches to 'staging' channel
232
+ 3. App receives staging bundle
233
+ 4. App applies staging updates
234
+ ```
235
+
236
+ ### E2E Test File Structure
237
+ ```
238
+ e2e/
239
+ ├── specs/
240
+ │ ├── ota-update.spec.js
241
+ │ ├── rollback.spec.js
242
+ │ ├── native-update.spec.js
243
+ │ └── channel-switching.spec.js
244
+ ├── helpers/
245
+ │ └── server-mock.js
246
+ └── setup.js
247
+ ```
248
+
249
+ ---
250
+
251
+ ## Test Server for E2E
252
+
253
+ A mock update server should provide:
254
+
255
+ ```javascript
256
+ // Mock endpoints
257
+ GET /api/updates/check?appId=xxx&version=1.0.0&channel=production
258
+ POST /api/updates/download/:bundleId
259
+ POST /api/updates/report
260
+ ```
261
+
262
+ The CLI already provides `npx native-update server start` for local testing.
263
+
264
+ ---
265
+
266
+ ## Security Testing Checklist
267
+
268
+ - [ ] Test with malformed bundle files (corrupted ZIP)
269
+ - [ ] Test with invalid checksums
270
+ - [ ] Test with expired/invalid signatures
271
+ - [ ] Test with HTTP URLs (should be rejected)
272
+ - [ ] Test downgrade attempts (should be blocked)
273
+ - [ ] Test oversized bundles (should respect limits)
274
+ - [ ] Test with network interruptions
275
+ - [ ] Test permission denial scenarios
276
+
277
+ ---
278
+
279
+ ## Test Implementation Status
280
+
281
+ All test categories have been implemented as of 2026-01-16:
282
+
283
+ | Category | Location | Tests | Status |
284
+ |----------|----------|-------|--------|
285
+ | TypeScript Unit Tests | `/src/__tests__/` | 9 test files | ✅ Complete |
286
+ | iOS Native Tests | `/ios/Tests/NativeUpdateTests/` | 5 test files, 32 tests | ✅ Complete |
287
+ | Android Native Tests | `/android/src/test/.../nativeupdate/` | 6 test files, 40 tests | ✅ Complete |
288
+ | E2E Tests | `/e2e/specs/` | 4 spec files, 19 tests | ✅ Complete |
289
+ | **Total** | | **~100 tests** | ✅ Complete |
290
+
291
+ ## Running All Tests
292
+
293
+ ```bash
294
+ # TypeScript Unit Tests
295
+ yarn test
296
+
297
+ # iOS Native Tests
298
+ cd ios && xcodebuild test -scheme NativeUpdate -destination 'platform=iOS Simulator,name=iPhone 15'
299
+
300
+ # Android Native Tests
301
+ cd android && ./gradlew test
302
+
303
+ # E2E Tests
304
+ cd e2e && yarn install && yarn test:android # or yarn test:ios
305
+ ```
306
+
307
+ ## Additional Testing
308
+
309
+ Manual testing is also supported through:
310
+ - Example apps for end-user testing
311
+ - CLI command verification
312
+ - Integration testing in production apps
@@ -0,0 +1,183 @@
1
+ # Backend Templates Guide
2
+
3
+ This guide explains the backend templates provided by the native-update CLI and how to customize them for your production environment.
4
+
5
+ ## Overview
6
+
7
+ The `npx native-update backend create <type>` command generates backend templates for managing OTA updates. These templates are **starting points** that require customization for your specific infrastructure.
8
+
9
+ ## Available Templates
10
+
11
+ | Template | Command | Use Case |
12
+ |----------|---------|----------|
13
+ | Express.js | `npx native-update backend create express` | Self-hosted Node.js server |
14
+ | Firebase | `npx native-update backend create firebase` | Serverless with Firebase Functions |
15
+ | Vercel | `npx native-update backend create vercel` | Serverless with Vercel Edge Functions |
16
+
17
+ ## Template Structure
18
+
19
+ Each template includes:
20
+
21
+ ```
22
+ native-update-backend/
23
+ ├── src/
24
+ │ ├── routes/
25
+ │ │ ├── updates.js # Update check/download endpoints
26
+ │ │ └── admin.js # Admin dashboard routes (if --with-admin)
27
+ │ ├── services/
28
+ │ │ ├── storage.js # Bundle storage service (CUSTOMIZE THIS)
29
+ │ │ └── database.js # Metadata storage (CUSTOMIZE THIS)
30
+ │ └── index.js # Entry point
31
+ ├── package.json
32
+ └── README.md
33
+ ```
34
+
35
+ ## Understanding Placeholder Code
36
+
37
+ The generated templates contain placeholder implementations marked with comments explaining what you need to implement. These are **intentional customization points**, not incomplete code.
38
+
39
+ ### Example: Storage Service
40
+
41
+ ```javascript
42
+ // storage.js - CUSTOMIZE FOR YOUR INFRASTRUCTURE
43
+ export async function storeBundle(bundleId, file) {
44
+ // Implement your storage logic here
45
+ // Options:
46
+ // - AWS S3: Use @aws-sdk/client-s3
47
+ // - Google Cloud Storage: Use @google-cloud/storage
48
+ // - Azure Blob: Use @azure/storage-blob
49
+ // - Local filesystem: Use fs/promises
50
+ throw new Error('Storage not configured - implement storeBundle()');
51
+ }
52
+
53
+ export async function getBundle(bundleId) {
54
+ // Implement your retrieval logic here
55
+ throw new Error('Storage not configured - implement getBundle()');
56
+ }
57
+ ```
58
+
59
+ ### Example: Database Service
60
+
61
+ ```javascript
62
+ // database.js - CUSTOMIZE FOR YOUR INFRASTRUCTURE
63
+ export async function saveBundleMetadata(metadata) {
64
+ // Implement your database logic here
65
+ // Options:
66
+ // - PostgreSQL: Use pg or prisma
67
+ // - MongoDB: Use mongoose
68
+ // - Firebase Firestore: Use firebase-admin
69
+ // - MySQL: Use mysql2
70
+ throw new Error('Database not configured - implement saveBundleMetadata()');
71
+ }
72
+ ```
73
+
74
+ ## Customization Guide
75
+
76
+ ### Step 1: Choose Your Storage
77
+
78
+ | Storage Option | Package | Best For |
79
+ |----------------|---------|----------|
80
+ | AWS S3 | `@aws-sdk/client-s3` | Production, scalable |
81
+ | Google Cloud Storage | `@google-cloud/storage` | GCP infrastructure |
82
+ | Azure Blob | `@azure/storage-blob` | Azure infrastructure |
83
+ | Local Filesystem | `fs/promises` | Development only |
84
+ | Cloudflare R2 | `@aws-sdk/client-s3` | Cost-effective |
85
+
86
+ ### Step 2: Choose Your Database
87
+
88
+ | Database Option | Package | Best For |
89
+ |----------------|---------|----------|
90
+ | PostgreSQL | `pg`, `prisma` | Production, relational |
91
+ | MongoDB | `mongoose` | Document-based |
92
+ | Firebase Firestore | `firebase-admin` | Serverless |
93
+ | SQLite | `better-sqlite3` | Small deployments |
94
+ | Redis | `ioredis` | Caching, fast reads |
95
+
96
+ ### Step 3: Implement the Services
97
+
98
+ Replace the placeholder functions with your actual implementations:
99
+
100
+ ```javascript
101
+ // Example: AWS S3 implementation
102
+ import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
103
+
104
+ const s3 = new S3Client({ region: process.env.AWS_REGION });
105
+
106
+ export async function storeBundle(bundleId, file) {
107
+ await s3.send(new PutObjectCommand({
108
+ Bucket: process.env.S3_BUCKET,
109
+ Key: `bundles/${bundleId}.zip`,
110
+ Body: file,
111
+ }));
112
+ return `bundles/${bundleId}.zip`;
113
+ }
114
+
115
+ export async function getBundle(bundleId) {
116
+ const response = await s3.send(new GetObjectCommand({
117
+ Bucket: process.env.S3_BUCKET,
118
+ Key: `bundles/${bundleId}.zip`,
119
+ }));
120
+ return response.Body;
121
+ }
122
+ ```
123
+
124
+ ## Template Options
125
+
126
+ ### --with-admin
127
+
128
+ Adds an admin dashboard for:
129
+ - Viewing deployed bundles
130
+ - Monitoring update adoption
131
+ - Managing channels
132
+ - Viewing device statistics
133
+
134
+ ### --with-monitoring
135
+
136
+ Adds monitoring endpoints for:
137
+ - Health checks
138
+ - Prometheus metrics
139
+ - Update success/failure rates
140
+ - Download statistics
141
+
142
+ ## Production Checklist
143
+
144
+ Before deploying to production:
145
+
146
+ - [ ] Implement storage service for your cloud provider
147
+ - [ ] Implement database service for metadata
148
+ - [ ] Configure environment variables
149
+ - [ ] Set up authentication for admin endpoints
150
+ - [ ] Configure HTTPS/TLS
151
+ - [ ] Set up rate limiting
152
+ - [ ] Configure logging (Winston, Pino, etc.)
153
+ - [ ] Set up error tracking (Sentry, etc.)
154
+ - [ ] Configure backup strategy for bundles
155
+
156
+ ## Environment Variables
157
+
158
+ Templates expect these environment variables:
159
+
160
+ ```env
161
+ # Server
162
+ PORT=3000
163
+ NODE_ENV=production
164
+
165
+ # Storage (example for S3)
166
+ AWS_REGION=us-east-1
167
+ S3_BUCKET=my-update-bundles
168
+ AWS_ACCESS_KEY_ID=xxx
169
+ AWS_SECRET_ACCESS_KEY=xxx
170
+
171
+ # Database (example for PostgreSQL)
172
+ DATABASE_URL=postgres://user:pass@host:5432/dbname
173
+
174
+ # Security
175
+ API_KEY=your-admin-api-key
176
+ SIGNING_PUBLIC_KEY_PATH=./keys/public.pem
177
+ ```
178
+
179
+ ## Related Documentation
180
+
181
+ - [Deployment Guide](./deployment-guide.md) - Full deployment instructions
182
+ - [Security Best Practices](./security-best-practices.md) - Security recommendations
183
+ - [Key Management](./key-management.md) - Managing signing keys
@@ -17,7 +17,7 @@
17
17
  2. **Development Tools** ✅
18
18
  - Bundle creation utility (`tools/bundle-creator.js`)
19
19
  - Bundle signing tool (`tools/bundle-signer.js`)
20
- - CLI tool (`cli/cap-update.js`)
20
+ - CLI tool (`cli/index.js`)
21
21
  - Testing framework with Vitest
22
22
  - Unit and integration tests
23
23
 
@@ -20,7 +20,7 @@ This document summarizes the current production readiness status of the capacito
20
20
  - Bundle creation utility (`tools/bundle-creator.js`)
21
21
  - Bundle signing tool (`tools/bundle-signer.js`)
22
22
  - Minimal backend server template (`backend-template/`)
23
- - CLI tool for easier usage (`cli/cap-update.js`)
23
+ - CLI tool for easier usage (`cli/index.js`)
24
24
 
25
25
  ### Core Features ✅
26
26
  - Client-side signature verification using Web Crypto API
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-update",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "description": "Foundation package for building a comprehensive update system for Capacitor apps. Provides architecture and interfaces but requires backend implementation.",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.cjs.js",
@@ -89,20 +89,20 @@
89
89
  "@rollup/plugin-json": "^6.1.0",
90
90
  "@rollup/plugin-node-resolve": "^16.0.3",
91
91
  "@rollup/plugin-terser": "^0.4.4",
92
- "@types/node": "^25.0.8",
92
+ "@types/node": "^25.0.9",
93
93
  "@typescript-eslint/eslint-plugin": "^8.53.0",
94
94
  "@typescript-eslint/parser": "^8.53.0",
95
95
  "@vitest/ui": "^4.0.17",
96
96
  "eslint": "^9.39.2",
97
- "happy-dom": "^20.1.0",
98
- "prettier": "^3.7.4",
97
+ "happy-dom": "^20.3.1",
98
+ "prettier": "^3.8.0",
99
99
  "rimraf": "^6.1.2",
100
100
  "rollup": "^4.55.1",
101
101
  "typescript": "^5.9.3",
102
102
  "vitest": "^4.0.17"
103
103
  },
104
104
  "peerDependencies": {
105
- "@capacitor/core": "^8.0.0"
105
+ "@capacitor/core": "^8.0.1"
106
106
  },
107
107
  "capacitor": {
108
108
  "ios": {
package/cli/cap-update.js DELETED
@@ -1,45 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from 'commander';
4
- import { readFileSync } from 'fs';
5
- import { resolve } from 'path';
6
-
7
- const program = new Command();
8
- const packageJson = JSON.parse(
9
- readFileSync(resolve(process.cwd(), 'package.json'), 'utf8')
10
- );
11
-
12
- program
13
- .name('cap-update')
14
- .description('CLI for Capacitor Native Update')
15
- .version('1.0.0');
16
-
17
- program
18
- .command('init')
19
- .description('Initialize update configuration')
20
- .option('-s, --server <url>', 'Update server URL')
21
- .action((options) => {
22
- console.log('Initializing Capacitor Native Update...');
23
- console.log('Server:', options.server || 'Not specified');
24
- // TODO: Create config file
25
- });
26
-
27
- program
28
- .command('bundle')
29
- .description('Create update bundle')
30
- .argument('<path>', 'Path to dist directory')
31
- .action((path) => {
32
- console.log(`Creating bundle from: ${path}`);
33
- // TODO: Call bundle creator
34
- });
35
-
36
- program
37
- .command('sign')
38
- .description('Sign update bundle')
39
- .argument('<bundle>', 'Bundle file path')
40
- .action((bundle) => {
41
- console.log(`Signing bundle: ${bundle}`);
42
- // TODO: Call bundle signer
43
- });
44
-
45
- program.parse();