Skip to content

Peer Connections & Secure Messaging#73

Open
Ananya44444 wants to merge 3 commits into
alphaonelabs:mainfrom
Ananya44444:msg
Open

Peer Connections & Secure Messaging#73
Ananya44444 wants to merge 3 commits into
alphaonelabs:mainfrom
Ananya44444:msg

Conversation

@Ananya44444

@Ananya44444 Ananya44444 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR introduces the Peer Connections & Messaging (A4) feature for the Cloudflare Workers-based Learn platform. It adds peer connection management, encrypted peer messaging, and secure messaging while following the existing architecture and conventions used by previous features.

Changes

Database

  • Added D1 migration for peer messaging.
  • Updated database schema with:
    • peer_connections
    • peer_messages
    • secure_messages

Backend

Implemented new REST APIs for:

  • Peer connection management

    • List connections
    • Discover/search users
    • Send connection requests
    • Accept/reject requests
  • Peer messaging

    • Retrieve conversation threads
    • Send encrypted messages
    • Connection validation before messaging
    • Read status updates
  • Secure messaging

    • Secure inbox
    • Send secure messages
    • Download secure messages
    • Star/unstar messages

Security

  • Uses the existing HMAC token authentication (verify_token)
  • Encrypts message content using the existing AES-GCM helpers
  • Integrates with the existing notification system

Frontend

Added new pages:

  • public/peers.html
  • public/peer-messages.html
  • public/secure-inbox.html

Features include:

  • User discovery
  • Connection requests
  • Accept/reject incoming requests
  • Peer chat interface
  • Secure inbox
  • Compose, download and star secure messages

Routing & Navigation

  • Registered all new API routes
  • Added navigation links for Peers and Secure Inbox
  • Updated messaging navigation to point to the new pages

Notes

  • No changes to the existing authentication flow.
  • Existing APIs and features remain unchanged.

This PR adds the “Peer Connections & Messaging (A4)” feature to the Cloudflare Workers-based Learn platform, enabling discovery, connection management, encrypted peer messaging, and a secure inbox experience.

Key backend changes include:

  • A new D1 schema/migration update introducing peer_connections, peer_messages, and secure_messages tables with constraints and indexes to support request status, message threading, and inbox/star/read flows.
  • New REST endpoints under /api/peers/* and /api/secure/* for:
    • User discovery and connection request/accept/reject workflows
    • Conversation threads with encrypted peer messages (including decrypt + read marking)
    • Secure inbox listing, secure message sending, download, and starring (including expiration metadata)
  • Integration with existing verify_token authentication and AES-GCM encryption helpers, and worker routing extended to dynamically dispatch these handlers.

Key frontend changes include:

  • New authenticated pages: public/peers.html, public/peer-messages.html, and public/secure-inbox.html, each using Bearer token calls, handling 401/403, and providing UI actions (send, refresh, star, download).
  • Navbar/navigation updates so “Messages” points to /peers.html and peer navigation is exposed in both desktop and mobile menus.

Testing updates:

  • Enhanced worker loading/caching behavior in test helpers and a D1 MockDB.batch stub.
  • Added tests/test_peers_api.py covering routing, auth/authorization (401/403), validation and constraint edge cases, and secure inbox star/download failure behavior.

Overall impact: authenticated users can discover each other, request/accept connections, exchange encrypted messages through peer threads, and manage secure messages via a dedicated secure inbox UI.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Ananya44444, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 149539eb-f311-41d4-bb93-df6acc32651f

📥 Commits

Reviewing files that changed from the base of the PR and between 9242643 and 441eb7e.

📒 Files selected for processing (1)
  • src/peers.py

Walkthrough

This PR adds peer connections, peer messaging, and secure inbox features. It introduces three new tables, a new backend module with API handlers, three client-side pages, navbar links, and tests for auth, validation, and dispatch routing.

Changes

Peer Connections and Secure Messaging

Layer / File(s) Summary
Database schema: peer_connections, peer_messages, secure_messages
schema.sql, src/worker.py
Adds the three new tables and supporting indexes in both schema definitions.
peers.py module init and helpers
src/peers.py
Adds dynamic worker loading plus helper functions for timestamps, notifications, user lookup, discovery, and connection serialization.
Peer connection and messaging API handlers
src/peers.py
Implements peer list, connect, accept/reject, thread fetch, and peer message send endpoints.
Secure messaging API handlers
src/peers.py
Implements secure inbox, send, download, and star-toggle endpoints plus recipient resolution.
worker.py dynamic loading and dispatch routing
src/worker.py
Loads peers.py lazily and routes /api/peers* and /api/secure* requests to it.
peers.html page: UI, auth, API calls
public/peers.html
Adds the peer connections page with discovery, pending, and connected views plus search and connection actions.
peer-messages.html page: thread UI and polling
public/peer-messages.html
Adds the peer message thread page with auth checks, thread loading, send form handling, and polling.
secure-inbox.html page: inbox, compose, star, download
public/secure-inbox.html
Adds the secure inbox page with inbox rendering, compose form, starring, and download actions.
Navbar wiring: Messages link and Peers menu entries
public/partials/navbar.html
Updates navigation to point Messages at the peers page and adds Peers entries in desktop and mobile menus.
Test helpers and peers API tests
tests/helpers.py, tests/test_peers_api.py
Adds worker module caching, DB batch support, and coverage for peers and secure messaging endpoints.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant api_connect as api_connect (peers.py)
  participant api_handle_connection as api_handle_connection (peers.py)
  participant api_send_peer_message as api_send_peer_message (peers.py)
  participant DB

  Browser->>api_connect: POST /api/peers/connect/{userId}
  api_connect->>DB: insert peer_connections (status=pending)
  Browser->>api_handle_connection: PATCH /api/peers/{id}/accept
  api_handle_connection->>DB: update status=accepted, notify sender
  Browser->>api_send_peer_message: POST /api/peers/messages/{peerId}
  api_send_peer_message->>DB: insert peer_messages (encrypted), update connection timestamp
  api_send_peer_message-->>Browser: ok response + notify recipient
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • A1L13N
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the new peer connections and secure messaging feature set.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 16

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@public/peer-messages.html`:
- Around line 40-42: The message compose input in the peer messages template
currently relies only on placeholder text, so add an accessible name for the
input identified by message-input in the send-form. Fix this by adding a real
label element with a for attribute tied to message-input, or by providing an
aria-label on the input, so screen readers can reliably identify the control.
- Around line 129-151: The send handler in send-form only disables
message-input, so the submit button can still be clicked and trigger duplicate
POSTs to api/peers/messages/:peer_id. Update the submit flow in the
addEventListener('submit', ...) handler to guard the entire form submission path
by disabling the submit control as well (and re-enabling it in the finally
block), using the existing input disable/restore pattern as the place to wire
this in.

In `@public/peers.html`:
- Around line 39-43: The search input in peers.html has no accessible name
because it relies only on placeholder text. Update the search control near the
searchUsers() button by adding a proper label tied to search-q (an sr-only label
is fine) or an aria-label on the input so assistive technologies can identify it
consistently.
- Around line 103-129: The pending requests UI in renderPending is filtering out
all sent items by keeping only direction === 'received', so sent requests never
appear after loadPeers merges data from both directions. Update renderPending in
peers.html to include the sent pending connections as well, and adjust the
displayed label/text so both received and sent requests are shown correctly in
the single pending list.

In `@public/secure-inbox.html`:
- Around line 38-42: The compose form controls in secure-inbox.html currently
rely only on placeholder text, so add explicit accessible labeling for the
recipient input and message textarea. Update the compose form markup around
compose-form, recipient, and message-body to use visible <label> elements or
equivalent aria-label/aria-labelledby attributes so assistive technologies can
announce both fields correctly.
- Around line 169-186: The secure inbox submit handler in the compose form can
fire multiple times while the `/api/secure/send` request is still pending,
causing duplicate sends. Update the submit flow in the compose form listener to
disable the form controls (or the submit action) before calling `apiFetch`, and
re-enable them in a finally-style path after the request settles, regardless of
success or failure. Use the existing `compose-form`, `recipient`, and
`message-body` elements in the submit handler to locate and lock/unlock the UI
state.

In `@schema.sql`:
- Around line 151-158: The peer_connections schema still allows duplicate
reciprocal rows because UNIQUE(sender_id, receiver_id) does not enforce an
unordered pair; update the CREATE TABLE definition to use a canonical-pair
uniqueness guarantee so A→B and B→A collide, and mirror the same DDL change in
src/worker.py’s _DDL. Make the change in the peer_connections table definition
and ensure api_connect relies on this database-level constraint instead of only
the pre-insert directional check.

In `@src/peers.py`:
- Around line 101-112: The peer search in the users lookup is limiting discovery
too early by only decrypting the newest 200 rows in the logic around
rows.results and matches. Update the search flow in peers.py so exact username
matches use a blind-index lookup first, and if you still need fuzzy name
matching, paginate through bounded decrypt scans until limit matches are
collected instead of stopping at a fixed 200-row window.
- Line 305: Validate the JSON field types before using string methods in the
request handlers that read body values, especially the content/recipient_id
extraction in the logic around parse_json_object(). For the affected spots in
the peer-handling flow, check that each expected field is a string before
calling .strip() or otherwise assuming string behavior, and return a 400
validation error when the type is wrong instead of letting AttributeError bubble
up as a 500.
- Around line 373-376: The secure-message retrieval paths in _format_expires(),
the inbox query, and the download/decrypt flow still return messages after their
7-day expiry. Update the query logic in the affected peers.py code paths to
exclude expired rows before any decryption or plaintext return, and add cleanup
plus tests that verify expired messages are no longer readable through inbox or
download. Use the existing secure_messages selection/decryption functions as the
main touchpoints so the fix applies consistently across both query sites.
- Around line 451-470: The api_secure_download handler currently performs a
destructive delete as a side effect of a GET request. Update this flow so
api_secure_download only returns the decrypted content, and move the deletion of
unstarred secure_messages into an explicit non-GET action such as a POST
acknowledge/delete endpoint or a separate delete endpoint. Keep the existing
auth, lookup, and decrypt logic in api_secure_download, but remove the
env.DB.batch deletion from this GET path and wire the one-time cleanup through a
dedicated handler instead.
- Around line 41-46: The _notify helper currently lets notification creation
failures bubble up from _worker()._create_notification, which can turn an
otherwise successful persisted write into a 500. Update _notify to be
best-effort by catching and logging exceptions around the notification call
(with enough context like user_id/type_/related_id), or restructure the write
path so the DB write and notification are truly atomic; keep the change
localized to _notify and its caller flow in peers.py.

In `@src/worker.py`:
- Around line 2782-2784: The peer module import in the request handler is too
early: `peers_api = _get_peers_module()` runs before checking whether the
request actually matches `/api/peers` or `/api/secure`, so unrelated `/api/*`
paths can fail with an import error instead of 404. Move the lazy import into
the matched branches or guard it with `path.startswith(("/api/peers",
"/api/secure"))` in the `worker.py` routing logic, and keep the existing error
handling/logging around `_get_peers_module()` so import failures are only
surfaced for the relevant peer/secure routes.

In `@tests/helpers.py`:
- Around line 22-27: The load_worker helper currently inserts the new worker
module into sys.modules before exec_module() runs, so a failure leaves a
half-initialized module cached. Update load_worker() to only keep the module in
sys.modules if spec.loader.exec_module(mod) succeeds, and remove the worker
entry from sys.modules in the exception path. Use the existing load_worker,
spec.loader.exec_module, and sys.modules["worker"] symbols to place the cleanup
close to the module-loading logic.

In `@tests/test_peers_api.py`:
- Around line 92-129: Add happy-path coverage for the newly introduced worker
routes and batch-backed flows in peers.api_handle_connection,
peers.api_send_message, peers.api_read_messages, peers.api_secure_send, and
peers.api_secure_download, plus the remaining /api/secure* dispatch branches in
TestPeersDispatch. Use existing symbols like worker.on_fetch, peers.*,
MockDB.batch, and the secure API entrypoints to verify successful responses and
correct route matching so method/regex mistakes or broken batch integration are
caught.
- Around line 17-28: The local test helpers in the test_peers_api module are
missing explicit return type annotations, which now violates the typing rule for
changed Python files. Update the _parse and _auth_header helper definitions to
include precise return annotations that match their actual outputs, and keep the
existing helper behavior unchanged; use the function names _parse, _enc, and
_auth_header to locate and adjust the signatures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e1d21c34-c10e-4b08-8385-42c64de9435f

📥 Commits

Reviewing files that changed from the base of the PR and between 997b01e and 50c0fe6.

⛔ Files ignored due to path filters (1)
  • migrations/0009_add_peer_messaging.sql is excluded by !**/migrations/**
📒 Files selected for processing (9)
  • public/partials/navbar.html
  • public/peer-messages.html
  • public/peers.html
  • public/secure-inbox.html
  • schema.sql
  • src/peers.py
  • src/worker.py
  • tests/helpers.py
  • tests/test_peers_api.py

Comment thread public/peer-messages.html
Comment thread public/peer-messages.html
Comment thread public/peers.html
Comment thread public/peers.html
Comment thread public/secure-inbox.html
Comment thread src/peers.py
Comment thread src/worker.py
Comment thread tests/helpers.py Outdated
Comment thread tests/test_peers_api.py Outdated
Comment thread tests/test_peers_api.py

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/peers.py`:
- Around line 43-52: Remove the redundant broad Exception handler in the
notification wrapper around _worker()._create_notification, since
_create_notification already owns the best-effort failure handling and logging.
Update the surrounding peer helper so it simply awaits the call without
swallowing unexpected loader/binding errors, and drop the explicit return None
to satisfy Ruff BLE001 and RET501 while keeping the behavior delegated to
_create_notification.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 16e8f336-7433-4660-8360-a59c817b78a3

📥 Commits

Reviewing files that changed from the base of the PR and between 50c0fe6 and 9242643.

⛔ Files ignored due to path filters (1)
  • migrations/0009_add_peer_messaging.sql is excluded by !**/migrations/**
📒 Files selected for processing (8)
  • public/peer-messages.html
  • public/peers.html
  • public/secure-inbox.html
  • schema.sql
  • src/peers.py
  • src/worker.py
  • tests/helpers.py
  • tests/test_peers_api.py

Comment thread src/peers.py Outdated
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