mirror of
https://github.com/xtr-dev/rondevu-server.git
synced 2025-12-10 10:53:24 +00:00
feat: Implement content-based offer IDs with SHA-256 hashing
- Added hash-id.ts utility for SHA-256 content hashing
- Offer IDs now generated from hash of {sdp, topics} (sorted)
- Removed peerId from hash (inferred from authentication)
- Server generates deterministic IDs for idempotent offer creation
- Updated SQLite and D1 storage implementations
- Removed optional id field from CreateOfferRequest
- Same offer content always produces same ID
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
51
src/middleware/auth.ts
Normal file
51
src/middleware/auth.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Context, Next } from 'hono';
|
||||
import { validateCredentials } from '../crypto.ts';
|
||||
|
||||
/**
|
||||
* Authentication middleware for Rondevu
|
||||
* Validates Bearer token in format: {peerId}:{encryptedSecret}
|
||||
*/
|
||||
export function createAuthMiddleware(authSecret: string) {
|
||||
return async (c: Context, next: Next) => {
|
||||
const authHeader = c.req.header('Authorization');
|
||||
|
||||
if (!authHeader) {
|
||||
return c.json({ error: 'Missing Authorization header' }, 401);
|
||||
}
|
||||
|
||||
// Expect format: Bearer {peerId}:{secret}
|
||||
const parts = authHeader.split(' ');
|
||||
if (parts.length !== 2 || parts[0] !== 'Bearer') {
|
||||
return c.json({ error: 'Invalid Authorization header format. Expected: Bearer {peerId}:{secret}' }, 401);
|
||||
}
|
||||
|
||||
const credentials = parts[1].split(':');
|
||||
if (credentials.length !== 2) {
|
||||
return c.json({ error: 'Invalid credentials format. Expected: {peerId}:{secret}' }, 401);
|
||||
}
|
||||
|
||||
const [peerId, encryptedSecret] = credentials;
|
||||
|
||||
// Validate credentials (async operation)
|
||||
const isValid = await validateCredentials(peerId, encryptedSecret, authSecret);
|
||||
if (!isValid) {
|
||||
return c.json({ error: 'Invalid credentials' }, 401);
|
||||
}
|
||||
|
||||
// Attach peer ID to context for use in handlers
|
||||
c.set('peerId', peerId);
|
||||
|
||||
await next();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get authenticated peer ID from context
|
||||
*/
|
||||
export function getAuthenticatedPeerId(c: Context): string {
|
||||
const peerId = c.get('peerId');
|
||||
if (!peerId) {
|
||||
throw new Error('No authenticated peer ID in context');
|
||||
}
|
||||
return peerId;
|
||||
}
|
||||
Reference in New Issue
Block a user