Skip to content

sync: update noot with latest from tacticalnoot/smol-fe main - #73

Closed
tacticalnoot wants to merge 1 commit into
kalepail:nootfrom
tacticalnoot:pr-noot
Closed

sync: update noot with latest from tacticalnoot/smol-fe main#73
tacticalnoot wants to merge 1 commit into
kalepail:nootfrom
tacticalnoot:pr-noot

Conversation

@tacticalnoot

Copy link
Copy Markdown

Sync noot branch with all latest changes from tacticalnoot/smol-fe main.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98c63dc5f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +31 to +32
let query = `SELECT * FROM messages WHERE room_id = ?`;
const args: any[] = [roomId];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce room authorization on chat message endpoints

After bearer-token validation, this handler immediately serves/stores messages for any room_id without checking whether the session is actually allowed in that room. Because /api/chat/rooms only computes unlocked for UI display, an authenticated user can bypass the client and call /api/chat/rooms/{locked-room}/messages directly to read or post restricted traffic. Add a server-side eligibility/room-status check in both GET and POST before querying or inserting.

Useful? React with 👍 / 👎.

Comment on lines +49 to +53
const newKey = nacl.randomBytes(32);
roomKeyHex = Buffer.from(newKey).toString('hex');
epoch = Date.now(); // Use timestamp as unique epoch ID

await db.prepare('INSERT INTO room_keys (room_id, key_material, epoch, created_at) VALUES (?, ?, ?, ?)').bind(roomId, roomKeyHex, epoch, Date.now()).run();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject unknown rooms before creating and returning room keys

This endpoint creates a fresh room key whenever room_id is missing from room_keys and then returns encrypted key material to the caller, but it never validates the room against the allowed room registry or access policy. In practice, any authenticated account can mint/access arbitrary room IDs (including disabled/hidden ones) and grow key rows unboundedly by requesting new IDs. Validate roomId and enforce authorization before key creation/return.

Useful? React with 👍 / 👎.

Comment on lines +59 to +63
function getGlobalStore(): VipStore {
const g = globalThis as unknown as Record<string, unknown>;
const existing = g[STORE_KEY] as VipStore | undefined;
if (existing) return existing;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist VIP session state outside isolate-local globals

VIP sessions and room state are stored in a globalThis map, which is process/isolate-local. On Cloudflare Pages/Workers, requests from one user can be served by different isolates, so tokens minted in /api/vip/verify may not exist when /api/vip/rooms/* is hit, causing intermittent 401s and fragmented room state under normal scaling. Move sessions/room state to shared persistence (e.g., D1/DO/KV or signed stateless tokens).

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant