native-update 1.4.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +13 -1
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +15 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +23 -7
- package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +152 -4
- package/android/src/main/java/com/aoneahsan/nativeupdate/NativeUpdatePlugin.kt +14 -1
- package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +10 -1
- package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +18 -18
- package/cli/AGENTS.md +29 -0
- package/cli/CLAUDE.md +51 -0
- package/dist/esm/__tests__/security-enforcement.test.d.ts +1 -0
- package/dist/esm/__tests__/security-enforcement.test.js +95 -0
- package/dist/esm/__tests__/security-enforcement.test.js.map +1 -0
- package/dist/esm/core/config.d.ts +6 -15
- package/dist/esm/core/config.js +1 -4
- package/dist/esm/core/config.js.map +1 -1
- package/dist/esm/core/security.d.ts +11 -3
- package/dist/esm/core/security.js +19 -6
- package/dist/esm/core/security.js.map +1 -1
- package/dist/esm/definitions.d.ts +38 -24
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/firestore/firestore-client.js +4 -0
- package/dist/esm/firestore/firestore-client.js.map +1 -1
- package/dist/esm/firestore/schema.d.ts +2 -0
- package/dist/esm/firestore/schema.js.map +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/live-update/download-manager.d.ts +36 -5
- package/dist/esm/live-update/download-manager.js +61 -22
- package/dist/esm/live-update/download-manager.js.map +1 -1
- package/dist/esm/live-update/update-manager.d.ts +12 -1
- package/dist/esm/live-update/update-manager.js +38 -10
- package/dist/esm/live-update/update-manager.js.map +1 -1
- package/dist/esm/live-update/version-manager.d.ts +9 -0
- package/dist/esm/live-update/version-manager.js +40 -0
- package/dist/esm/live-update/version-manager.js.map +1 -1
- package/dist/esm/plugin.js +95 -175
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/web.d.ts +18 -1
- package/dist/esm/web.js +69 -24
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +1 -1
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.esm.js +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist/plugin.js +2 -2
- package/dist/plugin.js.map +1 -1
- package/docs/AGENTS.md +38 -0
- package/docs/CHANGELOG.md +167 -0
- package/docs/CLAUDE.md +101 -0
- package/docs/MIGRATION.md +87 -0
- package/docs/README.md +13 -2
- package/docs/deployment/HOSTINGER_DEPLOY.md +329 -0
- package/docs/features/laravel-nova-backend/ASSESSMENT-SUMMARY.md +96 -0
- package/docs/features/laravel-nova-backend/IMPLEMENTATION-PLAN.md +504 -0
- package/docs/features/laravel-nova-backend/credentials.ignore.md +34 -0
- package/docs/features/laravel-nova-backend/progress-tracker.json +184 -0
- package/docs/guides/no-cost-backend-implementation-plan.md +77 -0
- package/docs/guides/no-cost-firestore-google-drive-backend.md +60 -0
- package/docs/project-knowledge-base/01-system-overview.md +218 -0
- package/docs/project-knowledge-base/02-routes-pages-forms-users.md +346 -0
- package/docs/project-knowledge-base/03-tech-stack-modules-services.md +347 -0
- package/docs/project-knowledge-base/04-data-models-integrations.md +307 -0
- package/docs/project-knowledge-base/05-docs-corpus-inventory.md +193 -0
- package/docs/project-knowledge-base/06-operations-testing-legal-content.md +170 -0
- package/docs/project-knowledge-base/README.md +90 -0
- package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-16.md +454 -0
- package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-24.md +66 -0
- package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-25.md +67 -0
- package/docs/seo-aeo-rules.json +3043 -0
- package/docs/tracking/seo-checklist-tracker.json +333 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +50 -6
- package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +238 -8
- package/ios/Plugin/NativeUpdatePlugin.swift +8 -0
- package/ios/Plugin/Security/SecurityManager.swift +13 -14
- package/package.json +31 -32
- package/docs/play-console-rejection-rules.json +0 -428
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
# Native Update - Laravel + Nova Backend Implementation Plan
|
|
2
|
+
|
|
3
|
+
**Created:** 2026-03-28
|
|
4
|
+
**Status:** Planning Complete
|
|
5
|
+
**Goal:** Transform native-update from a free Firebase-based system to a paid SaaS with Laravel + Nova backend
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
### Why This Change Is Needed
|
|
12
|
+
|
|
13
|
+
The native-update project is currently a fully functional OTA update system for Capacitor apps using a "no-cost" architecture (Firebase Auth + Firestore + Google Drive). However, to become a **paid commercial service** like Ionic AppFlow, we need:
|
|
14
|
+
|
|
15
|
+
1. **Licensing & API Keys** - Secure server-side key validation
|
|
16
|
+
2. **Stripe Payments** - Subscription management, usage-based billing (MAU)
|
|
17
|
+
3. **Secure Downloads** - API key-authenticated bundle downloads
|
|
18
|
+
4. **Server-Side Signing** - Private RSA keys held server-side
|
|
19
|
+
5. **Admin Dashboard** - Nova-powered backend for management
|
|
20
|
+
|
|
21
|
+
### Current State Assessment
|
|
22
|
+
|
|
23
|
+
| Component | Status | Production Ready |
|
|
24
|
+
|-----------|--------|------------------|
|
|
25
|
+
| TypeScript Plugin Core | Excellent | YES |
|
|
26
|
+
| Android Native | Good (minor fixes) | YES |
|
|
27
|
+
| iOS Native | Good (minor fixes) | YES |
|
|
28
|
+
| Firestore Schema | Complete | YES |
|
|
29
|
+
| Website (React) | Complete | YES |
|
|
30
|
+
| Security (Crypto) | Excellent | YES |
|
|
31
|
+
|
|
32
|
+
**The plugin itself is production-ready.** This plan focuses on the backend infrastructure for commercialization.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Architecture Decision
|
|
37
|
+
|
|
38
|
+
### Keep vs Migrate
|
|
39
|
+
|
|
40
|
+
| Component | Decision | Rationale |
|
|
41
|
+
|-----------|----------|-----------|
|
|
42
|
+
| **Frontend (React + Radix)** | KEEP | Working well, no migration needed |
|
|
43
|
+
| **Firebase Auth** | KEEP | Google OAuth working, validate tokens in Laravel |
|
|
44
|
+
| **Firestore** | MIGRATE to MySQL | Laravel needs relational data for billing |
|
|
45
|
+
| **Google Drive Storage** | OPTIONAL | Keep for free tier, add S3/R2 for paid |
|
|
46
|
+
| **Bundle Distribution** | MIGRATE | Laravel signed URLs for secure downloads |
|
|
47
|
+
|
|
48
|
+
### Final Architecture
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
52
|
+
│ FINAL ARCHITECTURE │
|
|
53
|
+
├─────────────────────────────────────────────────────────────────────┤
|
|
54
|
+
│ │
|
|
55
|
+
│ ┌─────────────┐ ┌─────────────────────┐ ┌──────────────┐ │
|
|
56
|
+
│ │ React │────▶│ Laravel API │────▶│ MySQL │ │
|
|
57
|
+
│ │ Dashboard │ │ (API + Nova Admin) │ │ Database │ │
|
|
58
|
+
│ │ (existing) │ │ │ │ │ │
|
|
59
|
+
│ └─────────────┘ │ - Stripe webhooks │ └──────────────┘ │
|
|
60
|
+
│ │ │ - Bundle signing │ │ │
|
|
61
|
+
│ │ │ - API key auth │ │ │
|
|
62
|
+
│ ▼ │ - MAU tracking │ ▼ │
|
|
63
|
+
│ ┌─────────────┐ └─────────────────────┘ ┌──────────────┐ │
|
|
64
|
+
│ │ Firebase │ │ │ S3/R2 │ │
|
|
65
|
+
│ │ Auth │ │ │ (bundles) │ │
|
|
66
|
+
│ │ (keep) │ ▼ │ │ │
|
|
67
|
+
│ └─────────────┘ ┌─────────────────────┐ └──────────────┘ │
|
|
68
|
+
│ │ Mobile Apps │ │
|
|
69
|
+
│ │ - API key auth │ │
|
|
70
|
+
│ │ - Signed URL DL │ │
|
|
71
|
+
│ └─────────────────────┘ │
|
|
72
|
+
│ │
|
|
73
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Implementation Phases
|
|
79
|
+
|
|
80
|
+
### Phase 1: Laravel Project Setup (Week 1)
|
|
81
|
+
|
|
82
|
+
**Tasks:**
|
|
83
|
+
1. Create Laravel 11 project with Nova 5
|
|
84
|
+
2. Configure MySQL database
|
|
85
|
+
3. Set up authentication (Firebase token validation middleware)
|
|
86
|
+
4. Configure S3/Cloudflare R2 for bundle storage
|
|
87
|
+
5. Set up development environment
|
|
88
|
+
|
|
89
|
+
**Files to Create:**
|
|
90
|
+
```
|
|
91
|
+
backend/
|
|
92
|
+
├── app/
|
|
93
|
+
│ ├── Http/
|
|
94
|
+
│ │ ├── Middleware/
|
|
95
|
+
│ │ │ ├── ValidateFirebaseToken.php
|
|
96
|
+
│ │ │ ├── ValidateApiKey.php
|
|
97
|
+
│ │ │ └── ValidateRequestSignature.php
|
|
98
|
+
│ │ └── Controllers/
|
|
99
|
+
│ │ └── Api/
|
|
100
|
+
│ │ ├── UpdateController.php
|
|
101
|
+
│ │ ├── BundleController.php
|
|
102
|
+
│ │ └── AnalyticsController.php
|
|
103
|
+
│ ├── Models/
|
|
104
|
+
│ │ ├── User.php
|
|
105
|
+
│ │ ├── App.php
|
|
106
|
+
│ │ ├── Build.php
|
|
107
|
+
│ │ ├── ApiKey.php
|
|
108
|
+
│ │ ├── Subscription.php
|
|
109
|
+
│ │ └── DeviceActivity.php
|
|
110
|
+
│ ├── Services/
|
|
111
|
+
│ │ ├── BundleSigningService.php
|
|
112
|
+
│ │ ├── SignedUrlService.php
|
|
113
|
+
│ │ └── MAUService.php
|
|
114
|
+
│ └── Nova/
|
|
115
|
+
│ ├── User.php
|
|
116
|
+
│ ├── App.php
|
|
117
|
+
│ ├── Build.php
|
|
118
|
+
│ ├── Subscription.php
|
|
119
|
+
│ └── Dashboards/
|
|
120
|
+
│ └── Main.php
|
|
121
|
+
├── config/
|
|
122
|
+
│ ├── firebase.php
|
|
123
|
+
│ └── stripe.php
|
|
124
|
+
├── database/
|
|
125
|
+
│ └── migrations/
|
|
126
|
+
│ ├── create_users_table.php
|
|
127
|
+
│ ├── create_apps_table.php
|
|
128
|
+
│ ├── create_builds_table.php
|
|
129
|
+
│ ├── create_api_keys_table.php
|
|
130
|
+
│ ├── create_subscriptions_table.php
|
|
131
|
+
│ └── create_device_activities_table.php
|
|
132
|
+
└── routes/
|
|
133
|
+
├── api.php
|
|
134
|
+
└── web.php
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Phase 2: Database Schema & Models (Week 1-2)
|
|
138
|
+
|
|
139
|
+
**Core Tables:**
|
|
140
|
+
|
|
141
|
+
```sql
|
|
142
|
+
-- users (synced from Firebase)
|
|
143
|
+
CREATE TABLE users (
|
|
144
|
+
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
145
|
+
firebase_uid VARCHAR(128) UNIQUE NOT NULL,
|
|
146
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
147
|
+
name VARCHAR(255),
|
|
148
|
+
avatar_url TEXT,
|
|
149
|
+
plan ENUM('free', 'pro', 'enterprise') DEFAULT 'free',
|
|
150
|
+
stripe_customer_id VARCHAR(255),
|
|
151
|
+
created_at TIMESTAMP,
|
|
152
|
+
updated_at TIMESTAMP
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
-- apps
|
|
156
|
+
CREATE TABLE apps (
|
|
157
|
+
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
158
|
+
user_id BIGINT UNSIGNED NOT NULL,
|
|
159
|
+
app_id VARCHAR(255) NOT NULL, -- com.example.app
|
|
160
|
+
name VARCHAR(255) NOT NULL,
|
|
161
|
+
platforms JSON, -- ['ios', 'android']
|
|
162
|
+
channels JSON, -- {production: {}, staging: {}}
|
|
163
|
+
public_key TEXT, -- RSA public key (auto-generated)
|
|
164
|
+
created_at TIMESTAMP,
|
|
165
|
+
updated_at TIMESTAMP,
|
|
166
|
+
FOREIGN KEY (user_id) REFERENCES users(id),
|
|
167
|
+
UNIQUE KEY (user_id, app_id)
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
-- api_keys
|
|
171
|
+
CREATE TABLE api_keys (
|
|
172
|
+
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
173
|
+
app_id BIGINT UNSIGNED NOT NULL,
|
|
174
|
+
key_hash VARCHAR(64) NOT NULL, -- SHA-256 of full key
|
|
175
|
+
key_prefix VARCHAR(20) NOT NULL, -- nu_app_abc123... (for display)
|
|
176
|
+
name VARCHAR(255),
|
|
177
|
+
type ENUM('app', 'admin') DEFAULT 'app',
|
|
178
|
+
status ENUM('active', 'deprecated', 'revoked') DEFAULT 'active',
|
|
179
|
+
permissions JSON,
|
|
180
|
+
rate_limit INT DEFAULT 60,
|
|
181
|
+
last_used_at TIMESTAMP,
|
|
182
|
+
expires_at TIMESTAMP,
|
|
183
|
+
created_at TIMESTAMP,
|
|
184
|
+
updated_at TIMESTAMP,
|
|
185
|
+
FOREIGN KEY (app_id) REFERENCES apps(id),
|
|
186
|
+
INDEX (key_hash),
|
|
187
|
+
INDEX (status)
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
-- builds
|
|
191
|
+
CREATE TABLE builds (
|
|
192
|
+
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
193
|
+
app_id BIGINT UNSIGNED NOT NULL,
|
|
194
|
+
bundle_id VARCHAR(255) NOT NULL,
|
|
195
|
+
version VARCHAR(50) NOT NULL,
|
|
196
|
+
build_number INT,
|
|
197
|
+
channel ENUM('production', 'staging', 'development') DEFAULT 'production',
|
|
198
|
+
platform ENUM('ios', 'android', 'web', 'all') DEFAULT 'all',
|
|
199
|
+
storage_path TEXT NOT NULL,
|
|
200
|
+
storage_provider ENUM('s3', 'r2', 'drive') DEFAULT 's3',
|
|
201
|
+
file_size BIGINT UNSIGNED,
|
|
202
|
+
checksum VARCHAR(64) NOT NULL, -- SHA-256
|
|
203
|
+
signature TEXT, -- RSA-PSS signature
|
|
204
|
+
release_notes TEXT,
|
|
205
|
+
mandatory BOOLEAN DEFAULT FALSE,
|
|
206
|
+
min_native_version VARCHAR(50),
|
|
207
|
+
rollout_percentage INT DEFAULT 100,
|
|
208
|
+
status ENUM('uploading', 'processing', 'active', 'archived', 'failed') DEFAULT 'uploading',
|
|
209
|
+
download_count INT DEFAULT 0,
|
|
210
|
+
install_count INT DEFAULT 0,
|
|
211
|
+
created_at TIMESTAMP,
|
|
212
|
+
updated_at TIMESTAMP,
|
|
213
|
+
FOREIGN KEY (app_id) REFERENCES apps(id),
|
|
214
|
+
INDEX (channel, status),
|
|
215
|
+
INDEX (version)
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
-- subscriptions
|
|
219
|
+
CREATE TABLE subscriptions (
|
|
220
|
+
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
221
|
+
user_id BIGINT UNSIGNED NOT NULL,
|
|
222
|
+
stripe_subscription_id VARCHAR(255),
|
|
223
|
+
stripe_price_id VARCHAR(255),
|
|
224
|
+
plan ENUM('free', 'pro', 'enterprise') NOT NULL,
|
|
225
|
+
status ENUM('active', 'canceled', 'past_due', 'trialing') DEFAULT 'active',
|
|
226
|
+
mau_limit INT NOT NULL, -- Monthly active users limit
|
|
227
|
+
apps_limit INT NOT NULL,
|
|
228
|
+
current_period_start TIMESTAMP,
|
|
229
|
+
current_period_end TIMESTAMP,
|
|
230
|
+
canceled_at TIMESTAMP,
|
|
231
|
+
created_at TIMESTAMP,
|
|
232
|
+
updated_at TIMESTAMP,
|
|
233
|
+
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
-- device_activities (for MAU tracking)
|
|
237
|
+
CREATE TABLE device_activities (
|
|
238
|
+
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
239
|
+
app_id BIGINT UNSIGNED NOT NULL,
|
|
240
|
+
device_hash VARCHAR(64) NOT NULL, -- SHA-256 of device ID
|
|
241
|
+
platform ENUM('ios', 'android', 'web'),
|
|
242
|
+
app_version VARCHAR(50),
|
|
243
|
+
bundle_version VARCHAR(50),
|
|
244
|
+
month_key VARCHAR(7) NOT NULL, -- '2026-03'
|
|
245
|
+
last_seen_at TIMESTAMP,
|
|
246
|
+
created_at TIMESTAMP,
|
|
247
|
+
FOREIGN KEY (app_id) REFERENCES apps(id),
|
|
248
|
+
UNIQUE KEY (app_id, device_hash, month_key),
|
|
249
|
+
INDEX (month_key)
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
-- signing_keys (RSA key pairs per app)
|
|
253
|
+
CREATE TABLE signing_keys (
|
|
254
|
+
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
255
|
+
app_id BIGINT UNSIGNED NOT NULL,
|
|
256
|
+
key_id VARCHAR(64) NOT NULL, -- fingerprint
|
|
257
|
+
private_key_encrypted TEXT NOT NULL, -- AES-256 encrypted
|
|
258
|
+
public_key TEXT NOT NULL,
|
|
259
|
+
status ENUM('active', 'rotated', 'revoked') DEFAULT 'active',
|
|
260
|
+
created_at TIMESTAMP,
|
|
261
|
+
rotated_at TIMESTAMP,
|
|
262
|
+
FOREIGN KEY (app_id) REFERENCES apps(id),
|
|
263
|
+
UNIQUE KEY (app_id, key_id)
|
|
264
|
+
);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Phase 3: API Endpoints (Week 2)
|
|
268
|
+
|
|
269
|
+
**Mobile App API (API Key Auth):**
|
|
270
|
+
|
|
271
|
+
| Method | Endpoint | Description |
|
|
272
|
+
|--------|----------|-------------|
|
|
273
|
+
| GET | `/api/v1/updates/check` | Check for available updates |
|
|
274
|
+
| GET | `/api/v1/bundles/{id}/download` | Download bundle (signed URL redirect) |
|
|
275
|
+
| POST | `/api/v1/analytics/mau` | Report device activity |
|
|
276
|
+
|
|
277
|
+
**Dashboard API (Firebase Token Auth):**
|
|
278
|
+
|
|
279
|
+
| Method | Endpoint | Description |
|
|
280
|
+
|--------|----------|-------------|
|
|
281
|
+
| GET | `/api/dashboard/apps` | List user's apps |
|
|
282
|
+
| POST | `/api/dashboard/apps` | Create new app |
|
|
283
|
+
| GET | `/api/dashboard/apps/{id}/builds` | List builds |
|
|
284
|
+
| POST | `/api/dashboard/apps/{id}/builds` | Upload new build |
|
|
285
|
+
| GET | `/api/dashboard/apps/{id}/keys` | List API keys |
|
|
286
|
+
| POST | `/api/dashboard/apps/{id}/keys` | Generate API key |
|
|
287
|
+
| GET | `/api/dashboard/subscription` | Get subscription status |
|
|
288
|
+
| POST | `/api/dashboard/subscription/checkout` | Create Stripe checkout |
|
|
289
|
+
|
|
290
|
+
**Webhook Endpoints:**
|
|
291
|
+
|
|
292
|
+
| Method | Endpoint | Description |
|
|
293
|
+
|--------|----------|-------------|
|
|
294
|
+
| POST | `/webhooks/stripe` | Stripe payment events |
|
|
295
|
+
|
|
296
|
+
### Phase 4: Stripe Integration (Week 2-3)
|
|
297
|
+
|
|
298
|
+
**Pricing Tiers:**
|
|
299
|
+
|
|
300
|
+
| Plan | Price | MAU Limit | Apps | Features |
|
|
301
|
+
|------|-------|-----------|------|----------|
|
|
302
|
+
| Free | $0 | 1,000 | 1 | Basic updates, community support |
|
|
303
|
+
| Pro | $29/mo | 10,000 | 5 | Rollouts, analytics, email support |
|
|
304
|
+
| Enterprise | $199/mo | 100,000 | Unlimited | Delta updates, SLA, priority support |
|
|
305
|
+
|
|
306
|
+
**MAU Overage:** $0.005 per MAU above limit
|
|
307
|
+
|
|
308
|
+
**Implementation:**
|
|
309
|
+
- Laravel Cashier for subscription management
|
|
310
|
+
- Stripe Checkout for self-serve signup
|
|
311
|
+
- Stripe Customer Portal for self-serve management
|
|
312
|
+
- Webhook handling for subscription lifecycle
|
|
313
|
+
|
|
314
|
+
### Phase 5: Bundle Signing & Security (Week 3)
|
|
315
|
+
|
|
316
|
+
**Server-Side Signing Flow:**
|
|
317
|
+
|
|
318
|
+
1. User uploads bundle via dashboard
|
|
319
|
+
2. Laravel receives file, stores in S3/R2
|
|
320
|
+
3. Calculate SHA-256 checksum
|
|
321
|
+
4. Sign with app's private RSA key (RSA-PSS, SHA-256)
|
|
322
|
+
5. Store signature in builds table
|
|
323
|
+
6. Return signed metadata to mobile apps
|
|
324
|
+
|
|
325
|
+
**Download Security:**
|
|
326
|
+
|
|
327
|
+
1. Mobile app requests update check with API key
|
|
328
|
+
2. Server validates API key + device eligibility
|
|
329
|
+
3. Generate time-limited signed URL (5 minutes)
|
|
330
|
+
4. URL bound to device ID hash
|
|
331
|
+
5. One-time download token
|
|
332
|
+
6. Mobile app downloads and verifies checksum + signature
|
|
333
|
+
|
|
334
|
+
### Phase 6: Nova Admin Panel (Week 3-4)
|
|
335
|
+
|
|
336
|
+
**Nova Resources:**
|
|
337
|
+
- Users - View all users, subscriptions, apps
|
|
338
|
+
- Apps - All apps across users
|
|
339
|
+
- Builds - All builds, status management
|
|
340
|
+
- Subscriptions - Revenue, plan management
|
|
341
|
+
- ApiKeys - Key management, revocation
|
|
342
|
+
- DeviceActivities - MAU reports
|
|
343
|
+
|
|
344
|
+
**Nova Dashboards:**
|
|
345
|
+
- Revenue Overview (MRR, churn, growth)
|
|
346
|
+
- Usage Metrics (MAU, downloads, installs)
|
|
347
|
+
- Build Analytics (success rate, rollback rate)
|
|
348
|
+
|
|
349
|
+
**Nova Actions:**
|
|
350
|
+
- Suspend User
|
|
351
|
+
- Adjust Plan
|
|
352
|
+
- Revoke API Key
|
|
353
|
+
- Archive Build
|
|
354
|
+
- Force Rollback
|
|
355
|
+
|
|
356
|
+
### Phase 7: Plugin Updates (Week 4)
|
|
357
|
+
|
|
358
|
+
**Changes to TypeScript Plugin:**
|
|
359
|
+
|
|
360
|
+
1. Add `apiKey` to `PluginInitConfig`
|
|
361
|
+
2. Add API key header to HTTP requests
|
|
362
|
+
3. Add request signing (optional, for replay protection)
|
|
363
|
+
4. Add MAU ping endpoint call
|
|
364
|
+
|
|
365
|
+
**Files to Modify:**
|
|
366
|
+
- `src/definitions.ts` - Add config interfaces
|
|
367
|
+
- `src/plugin.ts` - Add headers to fetch requests
|
|
368
|
+
- `src/core/config.ts` - API key validation
|
|
369
|
+
|
|
370
|
+
**Native Changes (minimal):**
|
|
371
|
+
- Store API key in secure storage (already supported)
|
|
372
|
+
- No other changes needed
|
|
373
|
+
|
|
374
|
+
### Phase 8: Migration & Testing (Week 4-5)
|
|
375
|
+
|
|
376
|
+
**Migration Strategy:**
|
|
377
|
+
|
|
378
|
+
1. Deploy Laravel backend alongside existing Firestore
|
|
379
|
+
2. Sync Firebase users to MySQL
|
|
380
|
+
3. Add HTTP backend support to plugin (already exists)
|
|
381
|
+
4. Migrate apps one-by-one
|
|
382
|
+
5. Deprecate Firestore (keep as fallback for 90 days)
|
|
383
|
+
6. Full cutover
|
|
384
|
+
|
|
385
|
+
**Testing Checklist:**
|
|
386
|
+
- [ ] API key generation and validation
|
|
387
|
+
- [ ] Bundle upload and signing
|
|
388
|
+
- [ ] Secure download URLs
|
|
389
|
+
- [ ] MAU tracking accuracy
|
|
390
|
+
- [ ] Stripe subscription flow
|
|
391
|
+
- [ ] Stripe webhook handling
|
|
392
|
+
- [ ] Nova admin operations
|
|
393
|
+
- [ ] Rate limiting
|
|
394
|
+
- [ ] Error handling
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Security Architecture
|
|
399
|
+
|
|
400
|
+
### API Key Format
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
nu_{type}_{random}_{checksum}
|
|
404
|
+
|
|
405
|
+
Example: nu_app_a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890_f7d8
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
- `nu_` - Namespace prefix
|
|
409
|
+
- `app_` or `adm_` - Key type
|
|
410
|
+
- 64 hex chars - Cryptographically secure random
|
|
411
|
+
- 4 hex chars - CRC-32 checksum
|
|
412
|
+
|
|
413
|
+
### Request Authentication
|
|
414
|
+
|
|
415
|
+
**Mobile Apps:**
|
|
416
|
+
```http
|
|
417
|
+
GET /api/v1/updates/check HTTP/1.1
|
|
418
|
+
Host: api.nativeupdate.dev
|
|
419
|
+
X-API-Key: nu_app_...
|
|
420
|
+
X-Device-ID: device_hash
|
|
421
|
+
X-Current-Version: 1.2.3
|
|
422
|
+
X-Platform: ios
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
**Dashboard:**
|
|
426
|
+
```http
|
|
427
|
+
GET /api/dashboard/apps HTTP/1.1
|
|
428
|
+
Host: api.nativeupdate.dev
|
|
429
|
+
Authorization: Bearer {firebase_id_token}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Bundle Signature Flow
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
1. Upload: bundle.zip
|
|
436
|
+
2. Server: checksum = SHA-256(bundle.zip)
|
|
437
|
+
3. Server: signature = RSA-PSS(checksum, private_key)
|
|
438
|
+
4. Store: {checksum, signature, key_id}
|
|
439
|
+
5. Mobile: verify RSA-PSS(checksum, signature, public_key)
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## File References
|
|
445
|
+
|
|
446
|
+
### Critical Plugin Files
|
|
447
|
+
- `/src/definitions.ts` - Add apiKey config
|
|
448
|
+
- `/src/plugin.ts` - Add auth headers (lines 362-368)
|
|
449
|
+
- `/src/core/security.ts` - Signature verification (existing)
|
|
450
|
+
- `/ios/Plugin/Security/SecurityManager.swift` - iOS secure storage
|
|
451
|
+
- `/android/.../SecurityManager.kt` - Android secure storage
|
|
452
|
+
|
|
453
|
+
### Website Files to Update
|
|
454
|
+
- `/website/src/services/bundle-upload-service.ts` - Change to Laravel API
|
|
455
|
+
- `/website/src/services/auth-service.ts` - Keep Firebase, add token forwarding
|
|
456
|
+
- `/website/src/stores/appsStore.ts` - Update API calls
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Verification Plan
|
|
461
|
+
|
|
462
|
+
### Unit Tests
|
|
463
|
+
- API key validation middleware
|
|
464
|
+
- Bundle signing service
|
|
465
|
+
- MAU calculation
|
|
466
|
+
- Subscription tier enforcement
|
|
467
|
+
|
|
468
|
+
### Integration Tests
|
|
469
|
+
- Full upload → download flow
|
|
470
|
+
- Stripe checkout → subscription active
|
|
471
|
+
- MAU tracking → billing calculation
|
|
472
|
+
- API key rotation
|
|
473
|
+
|
|
474
|
+
### End-to-End Tests
|
|
475
|
+
- Mobile app update check
|
|
476
|
+
- Mobile app bundle download
|
|
477
|
+
- Dashboard app creation
|
|
478
|
+
- Dashboard build upload
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
## Timeline Summary
|
|
483
|
+
|
|
484
|
+
| Week | Phase | Deliverables |
|
|
485
|
+
|------|-------|--------------|
|
|
486
|
+
| 1 | Setup + Schema | Laravel project, database, models |
|
|
487
|
+
| 2 | APIs | Mobile + Dashboard API endpoints |
|
|
488
|
+
| 2-3 | Stripe | Billing, subscriptions, webhooks |
|
|
489
|
+
| 3 | Security | Signing, secure downloads |
|
|
490
|
+
| 3-4 | Nova | Admin panel, dashboards |
|
|
491
|
+
| 4 | Plugin | TypeScript + native updates |
|
|
492
|
+
| 4-5 | Migration | Testing, gradual rollout |
|
|
493
|
+
|
|
494
|
+
**Total: 5 weeks to production**
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## Questions Resolved
|
|
499
|
+
|
|
500
|
+
1. **Keep Google Drive?** - Optional for free tier, S3/R2 for paid
|
|
501
|
+
2. **Keep Firebase Auth?** - YES, validate tokens in Laravel
|
|
502
|
+
3. **Mobile auth?** - API keys with signed URLs for downloads
|
|
503
|
+
4. **MAU tracking?** - Device hash + monthly aggregation
|
|
504
|
+
5. **Admin panel?** - Nova with full resource management
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Laravel Nova Credentials (GITIGNORED)
|
|
2
|
+
|
|
3
|
+
**File Pattern:** `*.ignore.*` - This file is excluded from git
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Nova License
|
|
8
|
+
|
|
9
|
+
| Field | Value |
|
|
10
|
+
|-------|-------|
|
|
11
|
+
| Email | Sajawal.developer@gmail.com |
|
|
12
|
+
| Key | koFe33Gb0rhbseLFlcUj4IGM0gKlLeWKGvQ64BxU4biZh4H4P6 |
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
When setting up Laravel project:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Add to composer.json
|
|
22
|
+
composer config http-basic.nova.laravel.com Sajawal.developer@gmail.com koFe33Gb0rhbseLFlcUj4IGM0gKlLeWKGvQ64BxU4biZh4H4P6
|
|
23
|
+
|
|
24
|
+
# Or set environment variables
|
|
25
|
+
export NOVA_LICENSE_EMAIL="Sajawal.developer@gmail.com"
|
|
26
|
+
export NOVA_LICENSE_KEY="koFe33Gb0rhbseLFlcUj4IGM0gKlLeWKGvQ64BxU4biZh4H4P6"
|
|
27
|
+
|
|
28
|
+
# Then install Nova
|
|
29
|
+
composer require laravel/nova
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
**Saved:** 2026-03-28
|