Skip to content

Add relay share invite endpoints#19

Merged
TraderSamwise merged 2 commits into
masterfrom
feat/multi-user-chat-invites
May 24, 2026
Merged

Add relay share invite endpoints#19
TraderSamwise merged 2 commits into
masterfrom
feat/multi-user-chat-invites

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented May 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • add authenticated relay endpoints for listing shares, creating email invites, and accepting invite tokens
  • fetch Clerk user profile data server-side and pass trusted actor headers into the owner Durable Object
  • add share invite email delivery support and production env defaults
  • redact invite token hashes from share summaries

Verification

  • yarn --cwd relay typecheck
  • yarn vitest run relay/src/sharing.test.ts
  • pre-push: yarn typecheck && yarn lint && yarn test

Note: Prettier cannot infer a parser for relay/wrangler.toml in this repo, so TOML was not run through prettier.

Summary by CodeRabbit

  • New Features
    • Session sharing with participant management and invite tracking
    • Sendable email invitations (Resend-based) with customizable invite base URL and from-address
    • Accept share invitations to join shared sessions
    • Authenticated request handling that attaches user identity (name/email) to forwarded requests
  • Privacy
    • Public share summaries redact sensitive invite tokens
  • Tests
    • Added test ensuring invite redaction in summaries

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 32e1a541-c092-4e8d-91fd-03a3e49ab3ea

📥 Commits

Reviewing files that changed from the base of the PR and between 389807d and 83ed7b2.

📒 Files selected for processing (3)
  • relay/src/index.ts
  • relay/src/relay-object.ts
  • relay/src/sharing-delivery.ts

📝 Walkthrough

Walkthrough

Adds Clerk-backed user profile lookup, three /shares HTTP routes (list, invite, accept) with header-injected identity, Resend-based email sending for invites, a public-safe share summary transformer, and related Env configuration.

Changes

Share Invite Flow with User Authentication and Email Delivery

Layer / File(s) Summary
Configuration and Environment Setup
relay/src/types.ts, relay/wrangler.toml
New optional Env fields COLLAB_EMAIL_FROM and SHARE_INVITE_BASE_URL and production vars added.
User Profile Fetching and Route Authentication
relay/src/auth.ts, relay/src/index.ts
fetchClerkUserProfile + ClerkUserProfile added; router imports profile fetch, validates Clerk bearer tokens, verifies tokens to get userId, attempts profile fetch (falls back to userId), and injects identity headers for share routes.
Share API HTTP Endpoints
relay/src/relay-object.ts
GET /shares, POST /shares/invite, and POST /shares/invite/{owner}/{token}/accept routed in RelayObject.fetch; handlers load/save durable sharing state, derive caller actor from headers, compute accept URL, and coordinate invite creation/acceptance.
Email Delivery via Resend API
relay/src/sharing-delivery.ts
deliverShareInvite sends invites via Resend when configured, renders HTML/plaintext bodies, escapes HTML, returns boolean for configured/unconfigured cases and throws on non-OK responses.
Share Summary Type and Redaction Logic
relay/src/sharing.ts, relay/src/sharing.test.ts
SharedSessionSummary and summarizeShare produce redacted, array-based summaries (omitting tokenHash); test verifies invite redaction while preserving email and status.

Sequence Diagram

sequenceDiagram
  participant Client
  participant RelayRouter
  participant ClerkAPI
  participant RelayObject
  participant DurableState
  participant ResendAPI
  Client->>RelayRouter: POST /shares/invite with Bearer token
  RelayRouter->>ClerkAPI: fetchClerkUserProfile (using CLERK_SECRET_KEY)
  ClerkAPI-->>RelayRouter: ClerkUserProfile (displayName,email)
  RelayRouter->>RelayObject: forward request with X-Aimux-User-* headers
  RelayObject->>DurableState: loadSharingState / saveSharingState
  DurableState-->>RelayObject: share record
  RelayObject->>RelayObject: createShareInvite / summarizeShare
  RelayObject->>ResendAPI: POST /emails (renderShareInviteEmail / shareInviteEmailText)
  ResendAPI-->>RelayObject: email sent
  RelayObject-->>Client: share summary + invite info
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • TraderSamwise/aimux#18: Share invite and participant management foundation that this PR builds upon with HTTP endpoints, user authentication, and email delivery.

Poem

🐇✨ I fetched a name with Clerk’s bright art,
Sent invites that flutter, a small work of heart,
Resend carried letters across the net,
Summaries hush secrets the public won’t get.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 'Add relay share invite endpoints' directly and clearly summarizes the main change: introducing new authenticated endpoints for managing share invites.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/multi-user-chat-invites

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

@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: 3

🤖 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 `@relay/src/index.ts`:
- Line 117: Wrap the call to fetchClerkUserProfile in a try/catch so
network/JSON errors don’t bubble up and cause a 500; on failure assign a safe
fallback profile (e.g., an object with userId and null/empty name/email or
minimal shape your downstream code expects) to the profile variable and continue
processing the /shares request. Ensure you reference fetchClerkUserProfile and
the local profile variable so downstream handlers still receive the expected
shape.

In `@relay/src/relay-object.ts`:
- Around line 417-440: The current flow persists the invite via
saveSharingState(this.ctx.storage, result.state) before calling
deliverShareInvite, which can cause “saved-but-400” when email send fails; fix
by reordering so deliverShareInvite({ env: this.env, owner, share:
result.token.share, inviteEmail: result.token.invite.email, acceptUrl }) is
attempted first and only on success call saveSharingState(this.ctx.storage,
result.state) and then return the 201 response; if you cannot reorder, instead
catch delivery errors and roll back the persisted state (e.g., delete the saved
invite/state) before returning an error, referencing saveSharingState and
deliverShareInvite and the result.token/result.state symbols to locate the code.

In `@relay/src/sharing-delivery.ts`:
- Around line 16-29: The fetch call posting to https://api.resend.com/emails
should check the HTTP response and fail on non-2xx statuses: assign the result
of fetch(...) to a variable (the POST that uses input.env.RESEND_API_KEY,
renderShareInviteEmail and shareInviteEmailText), then if (!response.ok) parse
response.json() or response.text() to capture error details and either throw or
log a descriptive error including response.status and the parsed body so invite
failures aren’t silently ignored.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b6edd65d-ffb9-4bcc-b7f8-f6c5754cce9d

📥 Commits

Reviewing files that changed from the base of the PR and between d410c59 and 389807d.

📒 Files selected for processing (8)
  • relay/src/auth.ts
  • relay/src/index.ts
  • relay/src/relay-object.ts
  • relay/src/sharing-delivery.ts
  • relay/src/sharing.test.ts
  • relay/src/sharing.ts
  • relay/src/types.ts
  • relay/wrangler.toml

Comment thread relay/src/index.ts Outdated
Comment thread relay/src/relay-object.ts
Comment thread relay/src/sharing-delivery.ts Outdated
@TraderSamwise

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@TraderSamwise
TraderSamwise merged commit 8f57cae into master May 24, 2026
1 check passed
@TraderSamwise
TraderSamwise deleted the feat/multi-user-chat-invites branch May 24, 2026 08:44
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