mirror of
https://github.com/xtr-dev/rondevu-server.git
synced 2025-12-12 03:43:23 +00:00
Expand README with links to related repositories and NPM packages
This commit is contained in:
@@ -29,6 +29,7 @@ export class D1Storage implements Storage {
|
||||
created_at INTEGER NOT NULL,
|
||||
expires_at INTEGER NOT NULL,
|
||||
last_seen INTEGER NOT NULL,
|
||||
secret TEXT,
|
||||
answerer_peer_id TEXT,
|
||||
answer_sdp TEXT,
|
||||
answered_at INTEGER
|
||||
@@ -75,9 +76,9 @@ export class D1Storage implements Storage {
|
||||
|
||||
// Insert offer
|
||||
await this.db.prepare(`
|
||||
INSERT INTO offers (id, peer_id, sdp, created_at, expires_at, last_seen)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`).bind(id, offer.peerId, offer.sdp, now, offer.expiresAt, now).run();
|
||||
INSERT INTO offers (id, peer_id, sdp, created_at, expires_at, last_seen, secret)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
`).bind(id, offer.peerId, offer.sdp, now, offer.expiresAt, now, offer.secret || null).run();
|
||||
|
||||
// Insert topics
|
||||
for (const topic of offer.topics) {
|
||||
@@ -95,6 +96,7 @@ export class D1Storage implements Storage {
|
||||
createdAt: now,
|
||||
expiresAt: offer.expiresAt,
|
||||
lastSeen: now,
|
||||
secret: offer.secret,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -175,7 +177,8 @@ export class D1Storage implements Storage {
|
||||
async answerOffer(
|
||||
offerId: string,
|
||||
answererPeerId: string,
|
||||
answerSdp: string
|
||||
answerSdp: string,
|
||||
secret?: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
// Check if offer exists and is not expired
|
||||
const offer = await this.getOfferById(offerId);
|
||||
@@ -187,6 +190,14 @@ export class D1Storage implements Storage {
|
||||
};
|
||||
}
|
||||
|
||||
// Verify secret if offer is protected
|
||||
if (offer.secret && offer.secret !== secret) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Invalid or missing secret'
|
||||
};
|
||||
}
|
||||
|
||||
// Check if offer already has an answerer
|
||||
if (offer.answererPeerId) {
|
||||
return {
|
||||
@@ -374,6 +385,7 @@ export class D1Storage implements Storage {
|
||||
createdAt: row.created_at,
|
||||
expiresAt: row.expires_at,
|
||||
lastSeen: row.last_seen,
|
||||
secret: row.secret || undefined,
|
||||
answererPeerId: row.answerer_peer_id || undefined,
|
||||
answerSdp: row.answer_sdp || undefined,
|
||||
answeredAt: row.answered_at || undefined,
|
||||
|
||||
@@ -30,6 +30,7 @@ export class SQLiteStorage implements Storage {
|
||||
created_at INTEGER NOT NULL,
|
||||
expires_at INTEGER NOT NULL,
|
||||
last_seen INTEGER NOT NULL,
|
||||
secret TEXT,
|
||||
answerer_peer_id TEXT,
|
||||
answer_sdp TEXT,
|
||||
answered_at INTEGER
|
||||
@@ -83,8 +84,8 @@ export class SQLiteStorage implements Storage {
|
||||
// Use transaction for atomic creation
|
||||
const transaction = this.db.transaction((offersWithIds: (CreateOfferRequest & { id: string })[]) => {
|
||||
const offerStmt = this.db.prepare(`
|
||||
INSERT INTO offers (id, peer_id, sdp, created_at, expires_at, last_seen)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
INSERT INTO offers (id, peer_id, sdp, created_at, expires_at, last_seen, secret)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
const topicStmt = this.db.prepare(`
|
||||
@@ -102,7 +103,8 @@ export class SQLiteStorage implements Storage {
|
||||
offer.sdp,
|
||||
now,
|
||||
offer.expiresAt,
|
||||
now
|
||||
now,
|
||||
offer.secret || null
|
||||
);
|
||||
|
||||
// Insert topics
|
||||
@@ -118,6 +120,7 @@ export class SQLiteStorage implements Storage {
|
||||
createdAt: now,
|
||||
expiresAt: offer.expiresAt,
|
||||
lastSeen: now,
|
||||
secret: offer.secret,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -195,7 +198,8 @@ export class SQLiteStorage implements Storage {
|
||||
async answerOffer(
|
||||
offerId: string,
|
||||
answererPeerId: string,
|
||||
answerSdp: string
|
||||
answerSdp: string,
|
||||
secret?: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
// Check if offer exists and is not expired
|
||||
const offer = await this.getOfferById(offerId);
|
||||
@@ -207,6 +211,14 @@ export class SQLiteStorage implements Storage {
|
||||
};
|
||||
}
|
||||
|
||||
// Verify secret if offer is protected
|
||||
if (offer.secret && offer.secret !== secret) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Invalid or missing secret'
|
||||
};
|
||||
}
|
||||
|
||||
// Check if offer already has an answerer
|
||||
if (offer.answererPeerId) {
|
||||
return {
|
||||
@@ -382,6 +394,7 @@ export class SQLiteStorage implements Storage {
|
||||
createdAt: row.created_at,
|
||||
expiresAt: row.expires_at,
|
||||
lastSeen: row.last_seen,
|
||||
secret: row.secret || undefined,
|
||||
answererPeerId: row.answerer_peer_id || undefined,
|
||||
answerSdp: row.answer_sdp || undefined,
|
||||
answeredAt: row.answered_at || undefined,
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface Offer {
|
||||
createdAt: number;
|
||||
expiresAt: number;
|
||||
lastSeen: number;
|
||||
secret?: string;
|
||||
answererPeerId?: string;
|
||||
answerSdp?: string;
|
||||
answeredAt?: number;
|
||||
@@ -44,6 +45,7 @@ export interface CreateOfferRequest {
|
||||
sdp: string;
|
||||
topics: string[];
|
||||
expiresAt: number;
|
||||
secret?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,9 +102,10 @@ export interface Storage {
|
||||
* @param offerId Offer identifier
|
||||
* @param answererPeerId Answerer's peer ID
|
||||
* @param answerSdp WebRTC answer SDP
|
||||
* @param secret Optional secret for protected offers
|
||||
* @returns Success status and optional error message
|
||||
*/
|
||||
answerOffer(offerId: string, answererPeerId: string, answerSdp: string): Promise<{
|
||||
answerOffer(offerId: string, answererPeerId: string, answerSdp: string, secret?: string): Promise<{
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
|
||||
Reference in New Issue
Block a user