@xtr-dev/rondevu-server 0.2.3 → 0.3.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 +77 -68
- package/dist/index.js +242 -105
- package/dist/index.js.map +2 -2
- package/migrations/0005_v2_schema.sql +83 -0
- package/package.json +1 -1
- package/src/app.ts +267 -139
- package/src/config.ts +1 -3
- package/src/crypto.ts +97 -0
- package/src/index.ts +0 -1
- package/src/storage/d1.ts +54 -7
- package/src/storage/hash-id.ts +4 -9
- package/src/storage/sqlite.ts +66 -15
- package/src/storage/types.ts +43 -10
- package/src/worker.ts +1 -3
- package/src/bloom.ts +0 -66
package/README.md
CHANGED
|
@@ -30,11 +30,11 @@ Username Claiming → Service Publishing → Service Discovery → WebRTC Connec
|
|
|
30
30
|
|
|
31
31
|
alice claims "alice" with Ed25519 signature
|
|
32
32
|
↓
|
|
33
|
-
alice publishes com.example.chat@1.0.0 → receives UUID abc123
|
|
33
|
+
alice publishes com.example.chat@1.0.0 with multiple offers → receives UUID abc123
|
|
34
34
|
↓
|
|
35
|
-
bob
|
|
35
|
+
bob requests alice/com.example.chat@1.0.0 → gets compatible service with available offer
|
|
36
36
|
↓
|
|
37
|
-
|
|
37
|
+
WebRTC connection established via offer/answer exchange
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
## Quick Start
|
|
@@ -77,15 +77,28 @@ Generates a cryptographically random 128-bit peer ID.
|
|
|
77
77
|
}
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
###
|
|
80
|
+
### User Management (RESTful)
|
|
81
81
|
|
|
82
|
-
#### `
|
|
82
|
+
#### `GET /users/:username`
|
|
83
|
+
Check username availability and claim status
|
|
84
|
+
|
|
85
|
+
**Response:**
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"username": "alice",
|
|
89
|
+
"available": false,
|
|
90
|
+
"claimedAt": 1733404800000,
|
|
91
|
+
"expiresAt": 1765027200000,
|
|
92
|
+
"publicKey": "..."
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### `POST /users/:username`
|
|
83
97
|
Claim a username with cryptographic proof
|
|
84
98
|
|
|
85
99
|
**Request:**
|
|
86
100
|
```json
|
|
87
101
|
{
|
|
88
|
-
"username": "alice",
|
|
89
102
|
"publicKey": "base64-encoded-ed25519-public-key",
|
|
90
103
|
"signature": "base64-encoded-signature",
|
|
91
104
|
"message": "claim:alice:1733404800000"
|
|
@@ -107,46 +120,37 @@ Claim a username with cryptographic proof
|
|
|
107
120
|
- Timestamp must be within 5 minutes (replay protection)
|
|
108
121
|
- Expires after 365 days, auto-renewed on use
|
|
109
122
|
|
|
110
|
-
#### `GET /
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
**Response:**
|
|
114
|
-
```json
|
|
115
|
-
{
|
|
116
|
-
"username": "alice",
|
|
117
|
-
"available": false,
|
|
118
|
-
"claimedAt": 1733404800000,
|
|
119
|
-
"expiresAt": 1765027200000,
|
|
120
|
-
"publicKey": "..."
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
+
#### `GET /users/:username/services/:fqn`
|
|
124
|
+
Get service by username and FQN with semver-compatible matching
|
|
123
125
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
**Semver Matching:**
|
|
127
|
+
- Requesting `chat@1.0.0` matches any `1.x.x` version
|
|
128
|
+
- Major version must match exactly (`chat@1.0.0` will NOT match `chat@2.0.0`)
|
|
129
|
+
- For major version 0, minor must also match (`0.1.0` will NOT match `0.2.0`)
|
|
130
|
+
- Returns the most recently published compatible version
|
|
126
131
|
|
|
127
132
|
**Response:**
|
|
128
133
|
```json
|
|
129
134
|
{
|
|
135
|
+
"uuid": "abc123",
|
|
136
|
+
"serviceId": "service-id",
|
|
130
137
|
"username": "alice",
|
|
131
|
-
"
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"isPublic": true,
|
|
139
|
-
"serviceFqn": "com.example.public@1.0.0",
|
|
140
|
-
"metadata": { "description": "Public service" }
|
|
141
|
-
}
|
|
142
|
-
]
|
|
138
|
+
"serviceFqn": "chat.app@1.0.0",
|
|
139
|
+
"offerId": "offer-hash",
|
|
140
|
+
"sdp": "v=0...",
|
|
141
|
+
"isPublic": true,
|
|
142
|
+
"metadata": {},
|
|
143
|
+
"createdAt": 1733404800000,
|
|
144
|
+
"expiresAt": 1733405100000
|
|
143
145
|
}
|
|
144
146
|
```
|
|
145
147
|
|
|
146
|
-
|
|
148
|
+
**Note:** Returns a single available offer from the service. If all offers are in use, returns 503.
|
|
149
|
+
|
|
150
|
+
### Service Management (RESTful)
|
|
147
151
|
|
|
148
|
-
#### `POST /services`
|
|
149
|
-
Publish a service (requires authentication and username signature)
|
|
152
|
+
#### `POST /users/:username/services`
|
|
153
|
+
Publish a service with multiple offers (requires authentication and username signature)
|
|
150
154
|
|
|
151
155
|
**Headers:**
|
|
152
156
|
- `Authorization: Bearer {peerId}:{secret}`
|
|
@@ -154,9 +158,11 @@ Publish a service (requires authentication and username signature)
|
|
|
154
158
|
**Request:**
|
|
155
159
|
```json
|
|
156
160
|
{
|
|
157
|
-
"username": "alice",
|
|
158
161
|
"serviceFqn": "com.example.chat@1.0.0",
|
|
159
|
-
"
|
|
162
|
+
"offers": [
|
|
163
|
+
{ "sdp": "v=0..." },
|
|
164
|
+
{ "sdp": "v=0..." }
|
|
165
|
+
],
|
|
160
166
|
"ttl": 300000,
|
|
161
167
|
"isPublic": false,
|
|
162
168
|
"metadata": { "description": "Chat service" },
|
|
@@ -165,12 +171,30 @@ Publish a service (requires authentication and username signature)
|
|
|
165
171
|
}
|
|
166
172
|
```
|
|
167
173
|
|
|
168
|
-
**Response:**
|
|
174
|
+
**Response (Full service details):**
|
|
169
175
|
```json
|
|
170
176
|
{
|
|
171
|
-
"serviceId": "uuid-v4",
|
|
172
177
|
"uuid": "uuid-v4-for-index",
|
|
173
|
-
"
|
|
178
|
+
"serviceId": "uuid-v4",
|
|
179
|
+
"username": "alice",
|
|
180
|
+
"serviceFqn": "com.example.chat@1.0.0",
|
|
181
|
+
"offers": [
|
|
182
|
+
{
|
|
183
|
+
"offerId": "offer-hash-1",
|
|
184
|
+
"sdp": "v=0...",
|
|
185
|
+
"createdAt": 1733404800000,
|
|
186
|
+
"expiresAt": 1733405100000
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"offerId": "offer-hash-2",
|
|
190
|
+
"sdp": "v=0...",
|
|
191
|
+
"createdAt": 1733404800000,
|
|
192
|
+
"expiresAt": 1733405100000
|
|
193
|
+
}
|
|
194
|
+
],
|
|
195
|
+
"isPublic": false,
|
|
196
|
+
"metadata": { "description": "Chat service" },
|
|
197
|
+
"createdAt": 1733404800000,
|
|
174
198
|
"expiresAt": 1733405100000
|
|
175
199
|
}
|
|
176
200
|
```
|
|
@@ -203,7 +227,7 @@ Get service details by UUID
|
|
|
203
227
|
}
|
|
204
228
|
```
|
|
205
229
|
|
|
206
|
-
#### `DELETE /services/:
|
|
230
|
+
#### `DELETE /users/:username/services/:fqn`
|
|
207
231
|
Unpublish a service (requires authentication and ownership)
|
|
208
232
|
|
|
209
233
|
**Headers:**
|
|
@@ -216,26 +240,6 @@ Unpublish a service (requires authentication and ownership)
|
|
|
216
240
|
}
|
|
217
241
|
```
|
|
218
242
|
|
|
219
|
-
### Service Discovery
|
|
220
|
-
|
|
221
|
-
#### `POST /index/:username/query`
|
|
222
|
-
Query a service by FQN
|
|
223
|
-
|
|
224
|
-
**Request:**
|
|
225
|
-
```json
|
|
226
|
-
{
|
|
227
|
-
"serviceFqn": "com.example.chat@1.0.0"
|
|
228
|
-
}
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**Response:**
|
|
232
|
-
```json
|
|
233
|
-
{
|
|
234
|
-
"uuid": "abc123",
|
|
235
|
-
"allowed": true
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
243
|
### Offer Management (Low-level)
|
|
240
244
|
|
|
241
245
|
#### `POST /offers`
|
|
@@ -259,9 +263,6 @@ Create one or more offers (requires authentication)
|
|
|
259
263
|
#### `GET /offers/mine`
|
|
260
264
|
List all offers owned by authenticated peer
|
|
261
265
|
|
|
262
|
-
#### `PUT /offers/:offerId/heartbeat`
|
|
263
|
-
Update last_seen timestamp for an offer
|
|
264
|
-
|
|
265
266
|
#### `DELETE /offers/:offerId`
|
|
266
267
|
Delete a specific offer
|
|
267
268
|
|
|
@@ -275,8 +276,8 @@ Answer an offer (locks it to answerer)
|
|
|
275
276
|
}
|
|
276
277
|
```
|
|
277
278
|
|
|
278
|
-
#### `GET /offers/
|
|
279
|
-
|
|
279
|
+
#### `GET /offers/:offerId/answer`
|
|
280
|
+
Get answer for a specific offer
|
|
280
281
|
|
|
281
282
|
#### `POST /offers/:offerId/ice-candidates`
|
|
282
283
|
Post ICE candidates for an offer
|
|
@@ -321,11 +322,19 @@ Environment variables:
|
|
|
321
322
|
- `id` (PK): Service ID (UUID)
|
|
322
323
|
- `username` (FK): Owner username
|
|
323
324
|
- `service_fqn`: Fully qualified name (com.example.chat@1.0.0)
|
|
324
|
-
- `offer_id` (FK): WebRTC offer ID
|
|
325
325
|
- `is_public`: Public/private flag
|
|
326
326
|
- `metadata`: JSON metadata
|
|
327
327
|
- `created_at`, `expires_at`: Timestamps
|
|
328
328
|
|
|
329
|
+
### offers
|
|
330
|
+
- `id` (PK): Offer ID (hash of SDP)
|
|
331
|
+
- `peer_id` (FK): Owner peer ID
|
|
332
|
+
- `service_id` (FK): Optional link to service (null for standalone offers)
|
|
333
|
+
- `sdp`: WebRTC offer SDP
|
|
334
|
+
- `answerer_peer_id`: Peer ID of answerer (null until answered)
|
|
335
|
+
- `answer_sdp`: WebRTC answer SDP (null until answered)
|
|
336
|
+
- `created_at`, `expires_at`, `last_seen`: Timestamps
|
|
337
|
+
|
|
329
338
|
### service_index (privacy layer)
|
|
330
339
|
- `uuid` (PK): Random UUID for discovery
|
|
331
340
|
- `service_id` (FK): Links to service
|