feat(cli): fetch AI summaries and video info from share links (#2015) - #2089
Conversation
…ack endpoints and add contract test (CapSoftware#2039)
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
| return Response.json(true, { status: 200 }); | ||
| } | ||
|
|
||
| export async function GET(request: NextRequest) { |
There was a problem hiding this comment.
P2: New video metadata endpoint lacks rate limiting
Public GET endpoint queries the database without throttling, enabling potential enumeration or DoS.
Add isRateLimited() with an appropriate RATE_LIMIT_IDS entry, matching the pattern in nearby endpoints.
AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.
<file name="apps/web/app/api/video/metadata/route.ts">
<violation number="1" location="apps/web/app/api/video/metadata/route.ts:43">
<priority>P2</priority>
<title>New video metadata endpoint lacks rate limiting</title>
<evidence>The new GET handler in apps/web/app/api/video/metadata/route.ts is publicly accessible for public videos and performs a database query on every request, but it does not apply any rate limiting. The same PR adds isRateLimited() calls to the analytics track and guest-checkout endpoints, indicating awareness of the need for rate limiting.</evidence>
<recommendation>Add rate limiting at the start of the GET handler using isRateLimited() and RATE_LIMIT_IDS, following the same pattern as the analytics/track and billing/guest-checkout endpoints in this PR.</recommendation>
</violation>
</file>
| if (!video.public && video.ownerId !== user?.id) { | ||
| return Response.json({ error: "Unauthorized" }, { status: 401 }); | ||
| } |
There was a problem hiding this comment.
Password-aware access is bypassed
When an unauthenticated caller requests a public video protected by a direct or inherited space password, this check treats video.public as sufficient authorization and returns its title, AI summary, and chapters without the required password. How this was verified: The endpoint's direct public check was compared with the canonical viewing policy, which verifies password candidates for public videos.
Knowledge Base Used: Web App (apps/web)
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/api/video/metadata/route.ts
Line: 60-62
Comment:
**Password-aware access is bypassed**
When an unauthenticated caller requests a public video protected by a direct or inherited space password, this check treats `video.public` as sufficient authorization and returns its title, AI summary, and chapters without the required password. **How this was verified:** The endpoint's direct public check was compared with the canonical viewing policy, which verifies password candidates for public videos.
**Knowledge Base Used:** [Web App (apps/web)](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/web-app.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| let video_id = if url_or_id.contains('/') { | ||
| url_or_id | ||
| .rsplit('/') | ||
| .next() | ||
| .unwrap_or(&url_or_id) | ||
| .to_string() | ||
| } else { | ||
| url_or_id | ||
| }; |
There was a problem hiding this comment.
For a share URL containing a query string, rsplit('/') includes that query in video_id, so the metadata endpoint looks up a value such as abc123?utm_source=... instead of abc123. Parse the URL and extract its final path segment, as the existing CLI target parser does.
Knowledge Base Used: Cap CLI (apps/cli)
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/cli/src/recordings.rs
Line: 111-119
Comment:
**Share URL queries enter IDs**
For a share URL containing a query string, `rsplit('/')` includes that query in `video_id`, so the metadata endpoint looks up a value such as `abc123?utm_source=...` instead of `abc123`. Parse the URL and extract its final path segment, as the existing CLI target parser does.
**Knowledge Base Used:** [Cap CLI (`apps/cli`)](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/cli.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| } | ||
|
|
||
| const meta = (video.metadata as Record<string, any>) ?? {}; | ||
|
|
There was a problem hiding this comment.
Metadata bypasses type narrowing
Casting metadata to Record<string, any> removes type checking from the new API boundary, preventing incompatible summary, chapter, or generation-status shapes from being detected. Use unknown with narrowing or an existing shared metadata type, as required by the repository's TypeScript guidance.
Context Used: AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/api/video/metadata/route.ts
Line: 65
Comment:
**Metadata bypasses type narrowing**
Casting metadata to `Record<string, any>` removes type checking from the new API boundary, preventing incompatible summary, chapter, or generation-status shapes from being detected. Use `unknown` with narrowing or an existing shared metadata type, as required by the repository's TypeScript guidance.
**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Fixes #2015
Summary
Greptile Summary
Adds a CLI command and web endpoint for retrieving video titles, AI summaries, chapters, and generation status, alongside rate limiting and teleprompter behavior adjustments.
cap recordings infowith text and JSON output.Confidence Score: 3/5
The PR should not merge until the metadata endpoint enforces password-aware video access, because it currently discloses protected summaries and chapters.
The new endpoint independently authorizes public videos without the canonical password checks, allowing unauthenticated metadata disclosure; the CLI URL parsing and metadata typing issues are additional non-blocking concerns.
Files Needing Attention: apps/web/app/api/video/metadata/route.ts, apps/cli/src/recordings.rs
Important Files Changed
Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat(cli): fetch AI summaries and video ..." | Re-trigger Greptile
Context used (5)
apps/cli)