@xtr-dev/rondevu-server 0.5.11 → 0.5.13

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.
@@ -3,15 +3,16 @@
3
3
  */
4
4
  export interface Offer {
5
5
  id: string;
6
- username: string;
6
+ publicKey: string; // Owner's Ed25519 public key
7
7
  tags: string[]; // Tags for discovery (match ANY)
8
8
  sdp: string;
9
9
  createdAt: number;
10
10
  expiresAt: number;
11
11
  lastSeen: number;
12
- answererUsername?: string;
12
+ answererPublicKey?: string;
13
13
  answerSdp?: string;
14
14
  answeredAt?: number;
15
+ matchedTags?: string[]; // Tags the answerer searched for to find this offer
15
16
  }
16
17
 
17
18
  /**
@@ -21,7 +22,7 @@ export interface Offer {
21
22
  export interface IceCandidate {
22
23
  id: number;
23
24
  offerId: string;
24
- username: string;
25
+ publicKey: string; // Sender's Ed25519 public key
25
26
  role: 'offerer' | 'answerer';
26
27
  candidate: any; // Full candidate object as JSON - don't enforce structure
27
28
  createdAt: number;
@@ -32,32 +33,12 @@ export interface IceCandidate {
32
33
  */
33
34
  export interface CreateOfferRequest {
34
35
  id?: string;
35
- username: string;
36
+ publicKey: string; // Owner's Ed25519 public key
36
37
  tags: string[]; // Tags for discovery
37
38
  sdp: string;
38
39
  expiresAt: number;
39
40
  }
40
41
 
41
- /**
42
- * Represents a credential (random name + secret pair)
43
- * Replaces the old username/publicKey system for simpler authentication
44
- */
45
- export interface Credential {
46
- name: string; // Random name (e.g., "brave-tiger-7a3f")
47
- secret: string; // Random secret (API key style)
48
- createdAt: number;
49
- expiresAt: number; // 365 days from creation/last use
50
- lastUsed: number;
51
- }
52
-
53
- /**
54
- * Request to generate new credentials
55
- */
56
- export interface GenerateCredentialsRequest {
57
- name?: string; // Optional: claim specific username (must be unique, 4-32 chars)
58
- expiresAt?: number; // Optional: override default expiry
59
- }
60
-
61
42
  /**
62
43
  * Storage interface for rondevu signaling system
63
44
  * Implementations can use different backends (SQLite, D1, etc.)
@@ -85,11 +66,11 @@ export interface Storage {
85
66
  createOffers(offers: CreateOfferRequest[]): Promise<Offer[]>;
86
67
 
87
68
  /**
88
- * Retrieves all offers from a specific user
89
- * @param username Username identifier
90
- * @returns Array of offers from the user
69
+ * Retrieves all offers from a specific owner
70
+ * @param publicKey Owner's Ed25519 public key
71
+ * @returns Array of offers from the owner
91
72
  */
92
- getOffersByUsername(username: string): Promise<Offer[]>;
73
+ getOffersByPublicKey(publicKey: string): Promise<Offer[]>;
93
74
 
94
75
  /**
95
76
  * Retrieves a specific offer by ID
@@ -101,10 +82,10 @@ export interface Storage {
101
82
  /**
102
83
  * Deletes an offer (with ownership verification)
103
84
  * @param offerId Offer identifier
104
- * @param ownerUsername Username of the owner (for verification)
85
+ * @param ownerPublicKey Public key of the owner (for verification)
105
86
  * @returns true if deleted, false if not found or not owned
106
87
  */
107
- deleteOffer(offerId: string, ownerUsername: string): Promise<boolean>;
88
+ deleteOffer(offerId: string, ownerPublicKey: string): Promise<boolean>;
108
89
 
109
90
  /**
110
91
  * Deletes all expired offers
@@ -116,43 +97,44 @@ export interface Storage {
116
97
  /**
117
98
  * Answers an offer (locks it to the answerer)
118
99
  * @param offerId Offer identifier
119
- * @param answererUsername Answerer's username
100
+ * @param answererPublicKey Answerer's public key
120
101
  * @param answerSdp WebRTC answer SDP
102
+ * @param matchedTags Optional tags the answerer searched for to find this offer
121
103
  * @returns Success status and optional error message
122
104
  */
123
- answerOffer(offerId: string, answererUsername: string, answerSdp: string): Promise<{
105
+ answerOffer(offerId: string, answererPublicKey: string, answerSdp: string, matchedTags?: string[]): Promise<{
124
106
  success: boolean;
125
107
  error?: string;
126
108
  }>;
127
109
 
128
110
  /**
129
111
  * Retrieves all answered offers for a specific offerer
130
- * @param offererUsername Offerer's username
112
+ * @param offererPublicKey Offerer's public key
131
113
  * @returns Array of answered offers
132
114
  */
133
- getAnsweredOffers(offererUsername: string): Promise<Offer[]>;
115
+ getAnsweredOffers(offererPublicKey: string): Promise<Offer[]>;
134
116
 
135
117
  /**
136
118
  * Retrieves all offers answered by a specific user (where they are the answerer)
137
- * @param answererUsername Answerer's username
119
+ * @param answererPublicKey Answerer's public key
138
120
  * @returns Array of offers the user has answered
139
121
  */
140
- getOffersAnsweredBy(answererUsername: string): Promise<Offer[]>;
122
+ getOffersAnsweredBy(answererPublicKey: string): Promise<Offer[]>;
141
123
 
142
124
  // ===== Discovery =====
143
125
 
144
126
  /**
145
127
  * Discovers offers by tags with pagination
146
- * Returns available offers (where answerer_username IS NULL) matching ANY of the provided tags
128
+ * Returns available offers (where answerer_public_key IS NULL) matching ANY of the provided tags
147
129
  * @param tags Array of tags to match (OR logic)
148
- * @param excludeUsername Optional username to exclude from results (self-exclusion)
130
+ * @param excludePublicKey Optional public key to exclude from results (self-exclusion)
149
131
  * @param limit Maximum number of offers to return
150
132
  * @param offset Number of offers to skip
151
133
  * @returns Array of available offers matching tags
152
134
  */
153
135
  discoverOffers(
154
136
  tags: string[],
155
- excludeUsername: string | null,
137
+ excludePublicKey: string | null,
156
138
  limit: number,
157
139
  offset: number
158
140
  ): Promise<Offer[]>;
@@ -160,12 +142,12 @@ export interface Storage {
160
142
  /**
161
143
  * Gets a random available offer matching any of the provided tags
162
144
  * @param tags Array of tags to match (OR logic)
163
- * @param excludeUsername Optional username to exclude (self-exclusion)
145
+ * @param excludePublicKey Optional public key to exclude (self-exclusion)
164
146
  * @returns Random available offer, or null if none found
165
147
  */
166
148
  getRandomOffer(
167
149
  tags: string[],
168
- excludeUsername: string | null
150
+ excludePublicKey: string | null
169
151
  ): Promise<Offer | null>;
170
152
 
171
153
  // ===== ICE Candidate Management =====
@@ -173,14 +155,14 @@ export interface Storage {
173
155
  /**
174
156
  * Adds ICE candidates for an offer
175
157
  * @param offerId Offer identifier
176
- * @param username Username posting the candidates
158
+ * @param publicKey Public key posting the candidates
177
159
  * @param role Role of the user (offerer or answerer)
178
160
  * @param candidates Array of candidate objects (stored as plain JSON)
179
161
  * @returns Number of candidates added
180
162
  */
181
163
  addIceCandidates(
182
164
  offerId: string,
183
- username: string,
165
+ publicKey: string,
184
166
  role: 'offerer' | 'answerer',
185
167
  candidates: any[]
186
168
  ): Promise<number>;
@@ -201,48 +183,16 @@ export interface Storage {
201
183
  /**
202
184
  * Retrieves ICE candidates for multiple offers (batch operation)
203
185
  * @param offerIds Array of offer identifiers
204
- * @param username Username requesting the candidates
186
+ * @param publicKey Public key requesting the candidates
205
187
  * @param since Optional timestamp - only return candidates after this time
206
188
  * @returns Map of offer ID to ICE candidates
207
189
  */
208
190
  getIceCandidatesForMultipleOffers(
209
191
  offerIds: string[],
210
- username: string,
192
+ publicKey: string,
211
193
  since?: number
212
194
  ): Promise<Map<string, IceCandidate[]>>;
213
195
 
214
- // ===== Credential Management =====
215
-
216
- /**
217
- * Generates a new credential (random name + secret)
218
- * @param request Credential generation request
219
- * @returns Created credential record
220
- */
221
- generateCredentials(request: GenerateCredentialsRequest): Promise<Credential>;
222
-
223
- /**
224
- * Gets a credential by name
225
- * @param name Credential name
226
- * @returns Credential record if found, null otherwise
227
- */
228
- getCredential(name: string): Promise<Credential | null>;
229
-
230
- /**
231
- * Updates credential usage timestamp and expiry
232
- * Called after successful signature verification
233
- * @param name Credential name
234
- * @param lastUsed Last used timestamp
235
- * @param expiresAt New expiry timestamp
236
- */
237
- updateCredentialUsage(name: string, lastUsed: number, expiresAt: number): Promise<void>;
238
-
239
- /**
240
- * Deletes all expired credentials
241
- * @param now Current timestamp
242
- * @returns Number of credentials deleted
243
- */
244
- deleteExpiredCredentials(now: number): Promise<number>;
245
-
246
196
  // ===== Rate Limiting =====
247
197
 
248
198
  /**
@@ -265,7 +215,7 @@ export interface Storage {
265
215
 
266
216
  /**
267
217
  * Check if nonce has been used and mark it as used (atomic operation)
268
- * @param nonceKey Unique nonce identifier (format: "nonce:{name}:{nonce}")
218
+ * @param nonceKey Unique nonce identifier (format: "nonce:{publicKey}:{nonce}")
269
219
  * @param expiresAt Timestamp when nonce expires (should be timestamp + timestampMaxAge)
270
220
  * @returns true if nonce is new (allowed), false if already used (replay attack)
271
221
  */
@@ -292,17 +242,11 @@ export interface Storage {
292
242
  getOfferCount(): Promise<number>;
293
243
 
294
244
  /**
295
- * Gets number of offers for a specific user
296
- * @param username Username identifier
297
- * @returns Offer count for user
298
- */
299
- getOfferCountByUsername(username: string): Promise<number>;
300
-
301
- /**
302
- * Gets total number of credentials in storage
303
- * @returns Total credential count
245
+ * Gets number of offers for a specific owner
246
+ * @param publicKey Owner's public key
247
+ * @returns Offer count for owner
304
248
  */
305
- getCredentialCount(): Promise<number>;
249
+ getOfferCountByPublicKey(publicKey: string): Promise<number>;
306
250
 
307
251
  /**
308
252
  * Gets number of ICE candidates for a specific offer
package/src/worker.ts CHANGED
@@ -7,7 +7,6 @@ import { buildWorkerConfig, runCleanup } from './config.ts';
7
7
  */
8
8
  export interface Env {
9
9
  DB: D1Database;
10
- MASTER_ENCRYPTION_KEY: string;
11
10
  OFFER_DEFAULT_TTL?: string;
12
11
  OFFER_MAX_TTL?: string;
13
12
  OFFER_MIN_TTL?: string;
@@ -19,11 +18,7 @@ export interface Env {
19
18
 
20
19
  export default {
21
20
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
22
- if (!env.MASTER_ENCRYPTION_KEY || env.MASTER_ENCRYPTION_KEY.length !== 64) {
23
- return new Response('MASTER_ENCRYPTION_KEY must be 64-char hex string', { status: 500 });
24
- }
25
-
26
- const storage = new D1Storage(env.DB, env.MASTER_ENCRYPTION_KEY);
21
+ const storage = new D1Storage(env.DB);
27
22
  const config = buildWorkerConfig(env);
28
23
  const app = createApp(storage, config);
29
24
 
@@ -31,14 +26,14 @@ export default {
31
26
  },
32
27
 
33
28
  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
34
- const storage = new D1Storage(env.DB, env.MASTER_ENCRYPTION_KEY);
29
+ const storage = new D1Storage(env.DB);
35
30
  const now = Date.now();
36
31
 
37
32
  try {
38
33
  const result = await runCleanup(storage, now);
39
- const total = result.offers + result.credentials + result.rateLimits + result.nonces;
34
+ const total = result.offers + result.rateLimits + result.nonces;
40
35
  if (total > 0) {
41
- console.log(`Cleanup: ${result.offers} offers, ${result.credentials} credentials, ${result.rateLimits} rate limits, ${result.nonces} nonces`);
36
+ console.log(`Cleanup: ${result.offers} offers, ${result.rateLimits} rate limits, ${result.nonces} nonces`);
42
37
  }
43
38
  } catch (error) {
44
39
  console.error('Cleanup error:', error);