@xtr-dev/rondevu-server 0.5.12 → 0.5.14

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