upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/PLAN.md
diff options
context:
space:
mode:
Diffstat (limited to 'PLAN.md')
-rw-r--r--PLAN.md98
1 files changed, 53 insertions, 45 deletions
diff --git a/PLAN.md b/PLAN.md
index c4373fb..a62959d 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -23,9 +23,9 @@ Build a TollGate firmware for two ESP32 devices, following the [TollGate protoco
23| Testing | Playwright + curl + pyserial | 23| Testing | Playwright + curl + pyserial |
24| Build | Makefile | 24| Build | Makefile |
25 25
26## Three-Phase Plan 26## Four-Phase Plan
27 27
28### Phase 1: Captive Portal + Firewall (No Payments) 28### Phase 1: Captive Portal + Firewall (No Payments) — COMPLETE
29 29
30**Goal:** WiFi repeater with captive portal that gates internet access. Validates DNS hijack, NAT, DHCP, firewall. 30**Goal:** WiFi repeater with captive portal that gates internet access. Validates DNS hijack, NAT, DHCP, firewall.
31 31
@@ -35,51 +35,55 @@ Build a TollGate firmware for two ESP32 devices, following the [TollGate protoco
35- Captive portal HTML on port 80 35- Captive portal HTML on port 80
36 36
37**14 Test Cases:** 37**14 Test Cases:**
38| # | Test | Method | Pass Criteria | 38| # | Test | Method | Pass Criteria | Status |
39|---|------|--------|---------------| 39|---|------|--------|---------------|--------|
40| 1 | Boot and AP appears | Serial + nmcli | SSID visible in scan | 40| 1 | Boot and AP appears | Serial + nmcli | SSID visible in scan | PASS |
41| 2 | DHCP lease | nmcli connect | Gets IP in 192.168.4.0/24 | 41| 2 | DHCP lease | nmcli connect | Gets IP in 192.168.4.0/24 | PASS |
42| 3 | Captive portal serves HTML | GET / | 200, contains "TollGate" | 42| 3 | Captive portal serves HTML | GET / | 200, contains "TollGate" | PASS |
43| 4 | Captive detection URIs work | GET /generate_204 etc. | All return portal HTML | 43| 4 | Captive detection URIs work | GET /generate_204 etc. | All return portal HTML | PASS |
44| 5 | DNS hijack before auth | nslookup google.com | Resolves to 192.168.4.1 | 44| 5 | DNS hijack before auth | nslookup google.com | Resolves to 192.168.4.1 | PASS |
45| 6 | No internet before auth | ping 8.8.8.8 | Fails | 45| 6 | No internet before auth | ping 8.8.8.8 | Fails | PASS |
46| 7 | /whoami returns MAC | GET /whoami | Returns mac=XX:XX:... | 46| 7 | /whoami returns MAC | GET /whoami | Returns mac=XX:XX:... | PASS |
47| 8 | /usage returns no session | GET /usage | Returns -1/-1 | 47| 8 | /usage returns no session | GET /usage | Returns -1/-1 | PASS |
48| 9 | Grant access via API | GET /grant_access | 200, status granted | 48| 9 | Grant access via API | GET /grant_access | 200, status granted | PASS |
49| 10 | DNS forward after auth | nslookup google.com | Resolves to real IP | 49| 10 | DNS forward after auth | nslookup google.com | Resolves to real IP | PASS |
50| 11 | Internet after auth | ping 8.8.8.8 | Succeeds | 50| 11 | Internet after auth | ping 8.8.8.8 | Succeeds | PASS |
51| 12 | HTTP browsing works | Playwright | Page loads | 51| 12 | HTTP browsing works | Playwright | Page loads | PASS |
52| 13 | Reset auth | GET /reset_authentication | 200 | 52| 13 | Reset auth | GET /reset_authentication | 200 | PASS |
53| 14 | Internet blocked after reset | ping 8.8.8.8 | Fails | 53| 14 | Internet blocked after reset | ping 8.8.8.8 | Fails | PASS |
54 54
55### Phase 2: E-Cash Payments (Simple Melt-to-LNURL) 55### Phase 2: E-Cash Payments IN PROGRESS
56 56
57**Goal:** Replace free access with Cashu payment. ESP32 parses token, melts via mint API to operator's LNURL. 57**Goal:** Replace free access with Cashu payment. ESP32 parses token, checks proof state via mint API, grants time-based session.
58 58
59**New Endpoints:** 59**Endpoints:**
60- `GET /` on :2121 — TollGate advertisement (kind=10021) 60- `GET /` on :2121 — TollGate advertisement (kind=10021)
61- `POST /` on :2121 — Accept Cashu token, melt, return session (kind=1022) or notice (kind=21023) 61- `POST /` on :2121 — Accept Cashu token, validate, return session (kind=1022) or error (kind=21023)
62- `GET /usage` on :2121 — Session usage info
63- `GET /whoami` on :2121 — Client IP + MAC
62 64
63**13 Additional Test Cases:** 65**13 Additional Test Cases:**
64| # | Test | Method | Pass Criteria | 66| # | Test | Method | Pass Criteria | Status |
65|---|------|--------|---------------| 67|---|------|--------|---------------|--------|
66| 15 | Advertisement valid | GET :2121/ | kind=10021 with price_per_step | 68| 15 | Advertisement valid | GET :2121/ | kind=10021 with price_per_step | PASS |
67| 16 | Valid payment | POST :2121/ with token | kind=1022 session | 69| 16 | Valid payment | POST :2121/ with token | kind=1022 session | PASS |
68| 17 | Usage tracking | GET :2121/usage | 0/allotment | 70| 17 | Usage tracking | GET :2121/usage | 0/allotment | PASS |
69| 18 | Internet after payment | ping | Succeeds | 71| 18 | Internet after payment | ping | Succeeds | PASS |
70| 19 | Invalid token | POST :2121/ garbage | kind=21023 error | 72| 19 | Invalid token | POST :2121/ garbage | kind=21023 error | PASS |
71| 20 | Spent token | Reuse token | kind=21023 spent error | 73| 20 | Spent token | Reuse token | kind=21023 spent error | PASS |
72| 21 | Wrong mint | Token from unaccepted mint | kind=21023 mint error | 74| 21 | Wrong mint | Token from unaccepted mint | kind=21023 mint error | PASS |
73| 22 | Session expiry | Wait for allotment | Internet blocked | 75| 22 | Session expiry | Wait for allotment | Internet blocked | TODO |
74| 23 | Session renewal | Second payment | Allotment extended | 76| 23 | Session renewal | Second payment | Allotment extended | TODO |
75| 24 | Portal payment form | Playwright paste token | Checkmark shown | 77| 24 | Portal payment form | Playwright paste token | Checkmark shown | TODO |
76| 25 | Two clients pay independently | Two POSTs | Both authenticated | 78| 25 | Two clients pay independently | Two POSTs | Both authenticated | TODO |
77| 26 | Client isolation | Only payer gets internet | Non-payer blocked | 79| 26 | Client isolation | Only payer gets internet | Non-payer blocked | TODO |
78| 27 | Full e2e: portal→pay→browse | Playwright | Complete flow | 80| 27 | Full e2e: portal→pay→browse | Playwright | Complete flow | TODO |
79 81
80### Phase 3: nucula Wallet Integration + Reseller 82**Captive Portal Fix:** Added DoT reject server on port 853 (TCP RST forces DNS-over-TLS fallback to plain DNS), DNS hijack returns NXDOMAIN for all non-A query types, explicit 302 redirect handlers for all captive detection URIs. Needs verification with actual GrapheneOS phone.
81 83
82**Goal:** Integrate nucula's full Cashu wallet. ESP32 holds balance, can be a reseller. 84### Phase 3: nucula Wallet + ESP32-to-ESP32 Payments — NOT STARTED
85
86**Goal:** Integrate nucula's full Cashu wallet. ESP32 holds balance, can be a reseller. ESP32-to-ESP32 direct payments.
83 87
84**11 Additional Test Cases:** 88**11 Additional Test Cases:**
85| # | Test | Method | Pass Criteria | 89| # | Test | Method | Pass Criteria |
@@ -96,4 +100,8 @@ Build a TollGate firmware for two ESP32 devices, following the [TollGate protoco
96| 37 | 5 consecutive payments | Loop | All authenticated | 100| 37 | 5 consecutive payments | Loop | All authenticated |
97| 38 | Stress: rapid pay/expire | Loop with short sessions | No crash/leak | 101| 38 | Stress: rapid pay/expire | Loop with short sessions | No crash/leak |
98 102
99## Total: 38 Tests across 3 phases 103### Phase 4: ESP32-to-OpenWRT TollGate Interop — NOT STARTED
104
105**Goal:** ESP32 can pay OpenWRT TollGate using Cashu tokens. Full interoperability with existing OpenWRT-based TollGate infrastructure.
106
107## Total: 38 Tests across 4 phases