Skip to content

Conversation

@ameer2468
Copy link
Contributor

@ameer2468 ameer2468 commented Aug 15, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Custom Domain verification more reliably detects subdomains and hides A‑record setup for them.
    • Fixed generation of media playlist URLs to ensure correct playback links.
  • Style

    • Verification panel is now a scrollable container with a capped height for improved readability on small screens and long instructions.
  • Chores

    • Added a robust domain parsing dependency; no public APIs or exported interfaces changed.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 15, 2025

Walkthrough

Adds tldts-based subdomain detection and an internal isSubdomain helper to VerifyStep, tightens A-record gating, makes the VerifyStep content scrollable, and adds the tldts dependency. Other edits are formatting/template fixes with no public API changes.

Changes

Cohort / File(s) Summary
VerifyStep UI & logic
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx
Added isSubdomain(raw: string) that normalizes input and calls parse from tldts with a dot-count fallback; updated A-record gating to require recommendedAValues.length > 0, domain not a subdomain, and not already configured; wrapped verification content with custom-scroll px-1 h-full max-h-[300px] space-y-4; no exported API changes.
Dependency added
apps/web/package.json
Added dependency "tldts": "^7.0.11".
Playlist route (template fix)
apps/web/app/api/playlist/route.ts
Fixed multi-line template literal interpolation for master playlist URLs (video/audio) and minor formatting adjustments; semantics unchanged.
Video delete route (imports/formatting)
apps/web/app/api/video/delete/route.ts
Removed unused HttpServerResponse import and minor formatting change; no behavior/API change.
S3Buckets formatting
packages/web-backend/src/S3Buckets/index.ts
Reformatted defaultConfigs to inline yield* endpoint expressions and adjusted punctuation/whitespace; logic and error handling unchanged.
Videos formatting
packages/web-backend/src/Videos/index.ts
Line-break/formatting changes around getById and service closing; no functional change.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant VerifyStep
  participant TLDTS

  User->>VerifyStep: Provide domain / open verification
  VerifyStep->>TLDTS: parse(normalize(domain))
  TLDTS-->>VerifyStep: parsed result (host, subdomain info)
  alt parsed indicates subdomain
    VerifyStep-->>User: Render verification UI WITHOUT A-record section
  else parsed indicates apex domain
    VerifyStep-->>User: Render verification UI WITH A-record section (if A-values present and not already configured)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Possibly related PRs

Poem

I hop through hosts and trim each name,
I call tldts to learn the domain.
If roots are clear, A-records I show,
If branches hide, that section won’t grow.
— a rabbit, nibbling code with a glow 🥕

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch handle-subdomains

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (1)

134-134: Scrolling container: avoid h-full to reduce layout coupling; prefer responsive max height

h-full can produce unexpected layouts depending on the parent’s height. You already cap with max-h-[300px]; consider relying on max height alone and making it responsive.

Apply this diff:

-<div className="overflow-y-auto h-full max-h-[300px] space-y-4">
+<div className="overflow-y-auto max-h-[60vh] space-y-4">

If you prefer a fixed cap, drop h-full and keep max-h-[300px]:

-<div className="overflow-y-auto h-full max-h-[300px] space-y-4">
+<div className="overflow-y-auto max-h-[300px] space-y-4">
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cc5ecbf and c05d9a2.

📒 Files selected for processing (1)
  • apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (1)

381-385: CNAME “Name” is computed incorrectly for multi-label TLDs and multi-label subdomains

Splitting by dots and taking the first label mislabels apex domains on public suffixes (e.g., example.co.uk becomes “example” instead of “@”) and drops nested labels (foo.bar.example.com should be “foo.bar”, not just “foo”). Use tldts to derive the subdomain safely.

Apply this targeted diff:

-<code className="px-2 py-1 text-xs rounded bg-gray-4">
-  {domain.split(".").length > 2
-    ? domain.split(".")[0]
-    : "@"}
-</code>
+<code className="px-2 py-1 text-xs rounded bg-gray-4">
+  {(() => {
+    const input = domain.trim().replace(/^https?:\/\//i, "").split("/")[0] ?? "";
+    const host = (input.replace(/\.$/, "").split(":")[0] || "").toLowerCase();
+    const { subdomain } = parse(host);
+    return subdomain || "@";
+  })()}
+</code>

Optionally, for clarity and reuse elsewhere, compute the label outside render:

// Place near other derived values
const normalizeHost = (raw: string) =>
  (raw.trim().replace(/^https?:\/\//i, "").split("/")[0] ?? "")
    .replace(/\.$/, "")
    .split(":")[0]
    .toLowerCase();

const { subdomain: domainSubdomain } = parse(normalizeHost(domain));

Then in JSX:

<code className="px-2 py-1 text-xs rounded bg-gray-4">
  {domainSubdomain || "@"}
</code>
♻️ Duplicate comments (1)
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (1)

86-87: A-record visibility gating is now correct and subdomain-aware

Switching to recommendedAValues.length > 0 and excluding subdomains fixes the earlier gating bug and aligns with expected behavior.

🧹 Nitpick comments (4)
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (4)

58-76: Robust subdomain detection; minor nit on try/catch

The normalization and tldts-based parsing are solid. Note that parse() doesn’t throw; the catch is unlikely to run. If you want to keep a fallback, consider checking parse(host).isIcann || parse(host).isPrivate and only falling back when parsing yields an invalid domain.

Apply this minimal diff if you prefer to simplify:

-  try {
-    // Prefer PSL-backed parsing for correctness (e.g., co.uk, com.au)
-    const { subdomain } = parse(host);
-    return Boolean(subdomain);
-  } catch {
-    // Fallback: conservative heuristic
-    const parts = host.split(".");
-    return parts.length > 2;
-  }
+  // Prefer PSL-backed parsing for correctness (e.g., co.uk, com.au)
+  const { subdomain } = parse(host);
+  return Boolean(subdomain);

147-147: Scrollable container: good UX, consider a responsive max-height

overflow-y-auto with a fixed max-h-[300px] works, but on tall viewports it can feel cramped. Consider a viewport-relative cap (e.g., 50–60vh) and drop h-full to avoid conflicting constraints.

Suggested tweak:

-<div className="overflow-y-auto h-full max-h-[300px] space-y-4">
+<div className="overflow-y-auto max-h-[60vh] space-y-4">

43-46: Avoid mutating arrays from props/state when sorting

recommendedIPv4.sort(...) mutates in place. Create a shallow copy before sorting to prevent side effects.

Apply this diff:

-  const sortedIPv4 = recommendedIPv4.sort((a, b) => a.rank - b.rank);
+  const sortedIPv4 = [...recommendedIPv4].sort((a, b) => a.rank - b.rank);

389-395: Don’t sort recommendedCnames in place during render

Sorting in place can cause subtle bugs across renders. Sort a copy before mapping.

Apply this diff:

- {recommendedCnames
-   .sort((a, b) => a.rank - b.rank)
-   .map((cname, index) => {
+ {[...recommendedCnames]
+   .sort((a, b) => a.rank - b.rank)
+   .map((cname, index) => {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2346c5b and 67438ff.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (4 hunks)
  • apps/web/package.json (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (2)
apps/web/package.json (1)

116-116: Add tldts dependency: LGTM

Brings in a robust PSL-backed parser for domain handling. No concerns on this change.

apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (1)

8-8: Using tldts.parse is the right call

This addresses public-suffix edge cases (e.g., co.uk, com.au) and is a solid foundation for subdomain logic.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
apps/web/app/api/video/delete/route.ts (1)

13-21: Declare all returned HttpApiError types (Unauthorized/InternalServerError) on the endpoint

The handler maps domain errors to HttpApiError.Unauthorized and HttpApiError.InternalServerError (Lines 31-45), but the endpoint only declares Forbidden and NotFound. This mismatch can cause type/runtime inconsistencies (e.g., validation rejecting undeclared errors). Either declare these errors or map to an already-declared type.

Apply this diff to declare the missing errors:

 class Api extends HttpApi.make("Api").add(
   HttpApiGroup.make("root").add(
     HttpApiEndpoint.del("deleteVideo")`/api/video/delete`
       .setUrlParams(Schema.Struct({ videoId: Video.VideoId }))
       .middleware(HttpAuthMiddleware)
       .addError(HttpApiError.Forbidden)
-      .addError(HttpApiError.NotFound),
+      .addError(HttpApiError.NotFound)
+      .addError(HttpApiError.Unauthorized)
+      .addError(HttpApiError.InternalServerError),
   ),
 ) {}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 67438ff and f82baf8.

📒 Files selected for processing (5)
  • apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (4 hunks)
  • apps/web/app/api/playlist/route.ts (2 hunks)
  • apps/web/app/api/video/delete/route.ts (1 hunks)
  • packages/web-backend/src/S3Buckets/index.ts (2 hunks)
  • packages/web-backend/src/Videos/index.ts (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/web-backend/src/Videos/index.ts
  • packages/web-backend/src/S3Buckets/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/app/api/playlist/route.ts (1)
packages/env/server.ts (1)
  • serverEnv (80-84)
🔇 Additional comments (2)
apps/web/app/api/video/delete/route.ts (1)

21-21: LGTM on class closing brace formatting

Purely stylistic change; consistent with repo formatting elsewhere.

apps/web/app/api/playlist/route.ts (1)

44-44: LGTM on class closing brace formatting

Cosmetic only; no behavioral impact.

@ameer2468 ameer2468 merged commit d70e25b into main Aug 15, 2025
14 of 15 checks passed
@ameer2468 ameer2468 deleted the handle-subdomains branch August 15, 2025 11:39
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (2)
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (2)

1-6: Add "use client" directive (component uses hooks but file isn't marked as client).

This component uses useState/useEffect, so it must be a client component. Without the directive, Next.js will error at build/runtime.

Apply this diff at the very top of the file:

+"use client";

381-385: Derive CNAME “Name” using tldts to support nested subdomains (e.g., a.b.example.co.uk).

Splitting by the first label yields only "a" for a.b.example…, which is misleading; many DNS providers expect the full subdomain part ("a.b").

Replace the naive split with PSL-backed parsing:

-                <code className="px-2 py-1 text-xs rounded bg-gray-4">
-                  {domain.split(".").length > 2
-                    ? domain.split(".")[0]
-                    : "@"}
-                </code>
+                <code className="px-2 py-1 text-xs rounded bg-gray-4">
+                  {parse(domain).subdomain || "@"}
+                </code>
🧹 Nitpick comments (4)
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (4)

58-76: Robust subdomain detection with PSL-backed parsing — looks solid.

Host normalization + tldts.parse(host) covers multi-label TLDs (co.uk, com.au), ports, and trailing dots. The conservative fallback is acceptable if parse ever fails.

If you want to shave a few bytes and avoid re-creating the function each render, you can hoist isSubdomain to module scope since it has no component dependencies.


43-45: Avoid mutating the input array when sorting IPv4 recommendations.

recommendedIPv4 comes from props; sorting it in-place can cause subtle side-effects across renders.

Use a non-mutating sort:

-      const sortedIPv4 = recommendedIPv4.sort((a, b) => a.rank - b.rank);
+      const sortedIPv4 = [...recommendedIPv4].sort((a, b) => a.rank - b.rank);

389-396: Non-mutating sort for CNAME recommendations.

.sort mutates recommendedCnames (from props). Prefer copying before sorting.

Apply:

-{recommendedCnames
-  .sort((a, b) => a.rank - b.rank)
+{[...recommendedCnames]
+  .sort((a, b) => a.rank - b.rank)
   .map((cname, index) => {
     const fieldId = `cname-${cname.rank}`;
     return (
       <div
         key={cname.rank}
         className="grid grid-cols-[100px,1fr] items-center"
       >

102-116: Stabilize polling interval typing and cleanup; include checkVerification in deps.

  • NodeJS.Timeout can be incorrect in the browser; use ReturnType.
  • Avoid clearing an uninitialized interval.
  • Add checkVerification to deps to prevent stale closure.
   useEffect(() => {
-    let interval: NodeJS.Timeout;
+    let interval: ReturnType<typeof setInterval> | null = null;
     if (activeOrganization?.organization.customDomain && !isVerified) {
       checkVerification(false);

-      interval = setInterval(() => {
+      interval = setInterval(() => {
         checkVerification(false);
       }, POLL_INTERVAL);
     }

     return () => {
-      clearInterval(interval);
+      if (interval) clearInterval(interval);
     };
-  }, [activeOrganization?.organization.customDomain, isVerified]);
+  }, [activeOrganization?.organization.customDomain, isVerified, checkVerification]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f82baf8 and f186f9e.

📒 Files selected for processing (1)
  • apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (3)
apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/VerifyStep.tsx (3)

86-88: Correct A-record gating condition.

Using recommendedAValues instead of a single requiredAValue covers IPv4 fallbacks and fixes the previously hidden section issue.


6-6: ✅ Dependency Confirmed & Approval
Good call using tldts for PSL-backed parsing. Static import keeps the bundle simple and enables reliable subdomain detection.
• Confirmed "tldts": "^7.0.11" is declared in apps/web/package.json.

Approved!


147-147: No changes needed—custom-scroll already enables vertical scrolling
The .custom-scroll class in apps/web/app/globals.css (lines 563–565) includes overflow-y: auto, so the container will scroll as intended.

@coderabbitai coderabbitai bot mentioned this pull request Sep 1, 2025
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.

2 participants