mirror of
https://github.com/xtr-dev/rondevu-server.git
synced 2025-12-13 20:33:25 +00:00
refactor: Unify polling endpoint and remove AUTH_SECRET
BREAKING CHANGES: - Renamed /offers/poll to /poll (generic polling endpoint) - Removed /offers/answered endpoint (use /poll instead) - Removed AUTH_SECRET environment variable (Ed25519 auth only) - Updated auth message format from 'pollOffers' to 'poll'
This commit is contained in:
34
README.md
34
README.md
@@ -309,37 +309,13 @@ Get answer SDP (offerer polls this)
|
|||||||
|
|
||||||
Returns 404 if not yet answered.
|
Returns 404 if not yet answered.
|
||||||
|
|
||||||
#### `GET /offers/answered`
|
#### `GET /poll`
|
||||||
Get all answered offers (efficient batch polling for offerer)
|
Combined polling endpoint for answers and ICE candidates
|
||||||
|
|
||||||
**Query Parameters:**
|
**Query Parameters:**
|
||||||
- `username` - Your username
|
- `username` - Your username
|
||||||
- `signature` - Base64-encoded Ed25519 signature
|
- `signature` - Base64-encoded Ed25519 signature
|
||||||
- `message` - Signed message (format: `getAnsweredOffers:{username}:{timestamp}`)
|
- `message` - Signed message (format: `poll:{username}:{timestamp}`)
|
||||||
- `since` - Optional timestamp to get only new answers
|
|
||||||
|
|
||||||
**Response:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"offers": [
|
|
||||||
{
|
|
||||||
"offerId": "offer-hash",
|
|
||||||
"serviceId": "service-uuid",
|
|
||||||
"answererUsername": "bob",
|
|
||||||
"sdp": "v=0...",
|
|
||||||
"answeredAt": 1733404800000
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `GET /offers/poll`
|
|
||||||
Combined polling for answers and ICE candidates (offerer)
|
|
||||||
|
|
||||||
**Query Parameters:**
|
|
||||||
- `username` - Your username
|
|
||||||
- `signature` - Base64-encoded Ed25519 signature
|
|
||||||
- `message` - Signed message (format: `pollOffers:{username}:{timestamp}`)
|
|
||||||
- `since` - Optional timestamp to get only new data
|
- `since` - Optional timestamp to get only new data
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
@@ -367,8 +343,6 @@ Combined polling for answers and ICE candidates (offerer)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
More efficient than polling answers and ICE separately - reduces HTTP requests by 50%.
|
|
||||||
|
|
||||||
#### `POST /services/:fqn/offers/:offerId/ice-candidates`
|
#### `POST /services/:fqn/offers/:offerId/ice-candidates`
|
||||||
Add ICE candidates to specific offer
|
Add ICE candidates to specific offer
|
||||||
|
|
||||||
@@ -517,7 +491,7 @@ See [MIGRATION.md](../MIGRATION.md) for detailed migration guide.
|
|||||||
- Removed UUID privacy layer - direct FQN-based access
|
- Removed UUID privacy layer - direct FQN-based access
|
||||||
- Removed public/private service distinction
|
- Removed public/private service distinction
|
||||||
- Added service discovery (random and paginated)
|
- Added service discovery (random and paginated)
|
||||||
- Added combined polling endpoint (/offers/poll)
|
- Unified polling endpoint (/poll replaces /offers/answered and /offers/poll)
|
||||||
- ICE candidate endpoints moved to offer-specific routes
|
- ICE candidate endpoints moved to offer-specific routes
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
36
src/app.ts
36
src/app.ts
@@ -507,43 +507,11 @@ export function createApp(storage: Storage, config: Config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /offers/answered
|
* GET /poll
|
||||||
* Get all answered offers for the authenticated peer (efficient batch polling)
|
|
||||||
*/
|
|
||||||
app.get('/offers/answered', authMiddleware, async (c) => {
|
|
||||||
try {
|
|
||||||
const username = getAuthenticatedUsername(c);
|
|
||||||
const since = c.req.query('since');
|
|
||||||
const sinceTimestamp = since ? parseInt(since, 10) : 0;
|
|
||||||
|
|
||||||
const offers = await storage.getAnsweredOffers(username);
|
|
||||||
|
|
||||||
// Filter by timestamp if provided
|
|
||||||
const filteredOffers = since
|
|
||||||
? offers.filter(offer => offer.answeredAt && offer.answeredAt > sinceTimestamp)
|
|
||||||
: offers;
|
|
||||||
|
|
||||||
return c.json({
|
|
||||||
offers: filteredOffers.map(offer => ({
|
|
||||||
offerId: offer.id,
|
|
||||||
serviceId: offer.serviceId,
|
|
||||||
answererId: offer.answererUsername,
|
|
||||||
sdp: offer.answerSdp,
|
|
||||||
answeredAt: offer.answeredAt
|
|
||||||
}))
|
|
||||||
}, 200);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error getting answered offers:', err);
|
|
||||||
return c.json({ error: 'Internal server error' }, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GET /offers/poll
|
|
||||||
* Combined efficient polling endpoint for answers and ICE candidates
|
* Combined efficient polling endpoint for answers and ICE candidates
|
||||||
* Returns all answered offers and ICE candidates for all peer's offers since timestamp
|
* Returns all answered offers and ICE candidates for all peer's offers since timestamp
|
||||||
*/
|
*/
|
||||||
app.get('/offers/poll', authMiddleware, async (c) => {
|
app.get('/poll', authMiddleware, async (c) => {
|
||||||
try {
|
try {
|
||||||
const username = getAuthenticatedUsername(c);
|
const username = getAuthenticatedUsername(c);
|
||||||
const since = c.req.query('since');
|
const since = c.req.query('since');
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { createApp } from './app.ts';
|
import { createApp } from './app.ts';
|
||||||
import { D1Storage } from './storage/d1.ts';
|
import { D1Storage } from './storage/d1.ts';
|
||||||
import { generateSecretKey } from './crypto.ts';
|
|
||||||
import { Config } from './config.ts';
|
import { Config } from './config.ts';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8,7 +7,6 @@ import { Config } from './config.ts';
|
|||||||
*/
|
*/
|
||||||
export interface Env {
|
export interface Env {
|
||||||
DB: D1Database;
|
DB: D1Database;
|
||||||
AUTH_SECRET?: string;
|
|
||||||
OFFER_DEFAULT_TTL?: string;
|
OFFER_DEFAULT_TTL?: string;
|
||||||
OFFER_MAX_TTL?: string;
|
OFFER_MAX_TTL?: string;
|
||||||
OFFER_MIN_TTL?: string;
|
OFFER_MIN_TTL?: string;
|
||||||
@@ -25,9 +23,6 @@ export default {
|
|||||||
// Initialize D1 storage
|
// Initialize D1 storage
|
||||||
const storage = new D1Storage(env.DB);
|
const storage = new D1Storage(env.DB);
|
||||||
|
|
||||||
// Generate or use provided auth secret
|
|
||||||
const authSecret = env.AUTH_SECRET || generateSecretKey();
|
|
||||||
|
|
||||||
// Build config from environment
|
// Build config from environment
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
port: 0, // Not used in Workers
|
port: 0, // Not used in Workers
|
||||||
|
|||||||
Reference in New Issue
Block a user