Skip to content

refactor: map Zoho Calendar location to known domains#28896

Open
pedroccastro wants to merge 2 commits intomainfrom
refactor/map-zoho-location-to-domain
Open

refactor: map Zoho Calendar location to known domains#28896
pedroccastro wants to merge 2 commits intomainfrom
refactor/map-zoho-location-to-domain

Conversation

@pedroccastro
Copy link
Copy Markdown
Contributor

What does this PR do?

Replaces the inline location → domain mapping in the Zoho Calendar OAuth callback with a shared helper (getValidZohoDomain) backed by an explicit map of supported Zoho data centers. Falls back to com for unknown locations.

Changes

  • New packages/app-store/zohocalendar/lib/zoho-domains.ts with LOCATION_TO_DOMAIN mapping covering the Zoho multi-DC domains (us, eu, in, cn, jp, au) and a getValidZohoDomain(location) helper
  • callback.ts uses the helper instead of the partial if (location === "us") ... else if (location === "au") ... else server_location = location block, which previously forwarded any string into the OAuth URL
  • Unit tests covering all known locations, undefined, and unknown inputs

How should this be tested?

TZ=UTC yarn vitest run packages/app-store/zohocalendar/lib/zoho-domains.test.ts                                

Manual

  1. Install Zoho Calendar from an account in each Zoho data center (us/eu/in/jp/au/cn) → OAuth flow completes against the correct Zoho domain
  2. Existing credentials (legacy server_location values in DB) continue to work

Mandatory Tasks

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • N/A I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 15, 2026

📝 Walkthrough

Walkthrough

This pull request refactors the Zoho Calendar integration to centralize location-to-domain mapping logic. Previously, the callback handler contained inline conditional logic to map location codes to Zoho domain suffixes. A new shared helper function getValidZohoDomain replaces this inline mapping, along with corresponding test coverage. The function maps datacenter locations (us, eu, in, cn, jp, au) to their respective domain suffixes and returns a default domain when the location is undefined or unrecognized.

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: refactoring the Zoho Calendar location-to-domain mapping into a shared helper function, which is the core purpose of this PR.
Description check ✅ Passed The description clearly relates to the changeset, explaining what was changed (inline mapping replaced with getValidZohoDomain helper), why (centralized location normalization), and how to test it.

✏️ 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 refactor/map-zoho-location-to-domain

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 and usage tips.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app-store/zohocalendar/lib/zoho-domains.ts`:
- Around line 13-15: The getValidZohoDomain function currently indexes
LOCATION_TO_DOMAIN with the raw location value which allows prototype keys like
"toString" to resolve inherited properties; update getValidZohoDomain to first
ensure location is a plain string and then check membership using a safe
own-property check (e.g.,
Object.prototype.hasOwnProperty.call(LOCATION_TO_DOMAIN, location) or
Object.hasOwn) before returning LOCATION_TO_DOMAIN[location]; if the check fails
return DEFAULT_DOMAIN (still allow the existing "us" default when location is
undefined). Reference getValidZohoDomain, LOCATION_TO_DOMAIN, and DEFAULT_DOMAIN
when making the change.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 12f15c6f-d2e6-4fd2-a0b0-9aadbfb1ca6a

📥 Commits

Reviewing files that changed from the base of the PR and between a17f28e and bad97b9.

📒 Files selected for processing (3)
  • packages/app-store/zohocalendar/api/callback.ts
  • packages/app-store/zohocalendar/lib/zoho-domains.test.ts
  • packages/app-store/zohocalendar/lib/zoho-domains.ts

Comment on lines +13 to +15
export function getValidZohoDomain(location: string | undefined): string {
return LOCATION_TO_DOMAIN[location || "us"] || DEFAULT_DOMAIN;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify current behavior with prototype-inherited key vs safe hasOwn check.
node <<'NODE'
const LOCATION_TO_DOMAIN = { us:"com", eu:"eu", in:"in", cn:"com.cn", jp:"jp", au:"com.au" };
const probe = "toString";

const current = LOCATION_TO_DOMAIN[probe] || "com";
const safe = Object.prototype.hasOwnProperty.call(LOCATION_TO_DOMAIN, probe)
  ? LOCATION_TO_DOMAIN[probe]
  : "com";

console.log("current_type:", typeof current);
console.log("current_preview:", String(current).slice(0, 60));
console.log("safe_value:", safe);
NODE

Repository: calcom/cal.com

Length of output: 151


🏁 Script executed:

# Check if the file exists and read the relevant code
cat -n packages/app-store/zohocalendar/lib/zoho-domains.ts | head -30

Repository: calcom/cal.com

Length of output: 572


🏁 Script executed:

# Search for usages of getValidZohoDomain to understand the threat surface
rg "getValidZohoDomain" --type ts --type tsx -B 2 -A 2

Repository: calcom/cal.com

Length of output: 85


🏁 Script executed:

# Check if LOCATION_TO_DOMAIN is accessed elsewhere in unsafe ways
rg "LOCATION_TO_DOMAIN" --type ts --type tsx -B 2 -A 2

Repository: calcom/cal.com

Length of output: 85


🏁 Script executed:

# Find usages of getValidZohoDomain with simpler rg command
rg "getValidZohoDomain" -A 2 -B 2

Repository: calcom/cal.com

Length of output: 3081


🏁 Script executed:

# Also check if location parameter comes from user input (query params, request body, etc.)
rg "location" packages/app-store/zohocalendar --type-not json -A 1 -B 1 | head -50

Repository: calcom/cal.com

Length of output: 3801


Prototype-key inputs can bypass unknown-location fallback.

In packages/app-store/zohocalendar/api/callback.ts, the location parameter comes directly from req.query. Prototype keys like "toString" will resolve inherited Object properties, allowing non-domain values to flow into URL construction. The current fallback LOCATION_TO_DOMAIN[location || "us"] || DEFAULT_DOMAIN does not filter these.

🛠️ Proposed fix
-const LOCATION_TO_DOMAIN: Record<string, string> = {
+const LOCATION_TO_DOMAIN = {
   us: "com",
   eu: "eu",
   in: "in",
   cn: "com.cn",
   jp: "jp",
   au: "com.au",
-};
+} as const;
+type ZohoLocation = keyof typeof LOCATION_TO_DOMAIN;

 const DEFAULT_DOMAIN = "com";

+function isZohoLocation(location: string): location is ZohoLocation {
+  return Object.prototype.hasOwnProperty.call(LOCATION_TO_DOMAIN, location);
+}
+
 export function getValidZohoDomain(location: string | undefined): string {
-  return LOCATION_TO_DOMAIN[location || "us"] || DEFAULT_DOMAIN;
+  if (!location) return DEFAULT_DOMAIN;
+  return isZohoLocation(location) ? LOCATION_TO_DOMAIN[location] : DEFAULT_DOMAIN;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function getValidZohoDomain(location: string | undefined): string {
return LOCATION_TO_DOMAIN[location || "us"] || DEFAULT_DOMAIN;
}
const LOCATION_TO_DOMAIN = {
us: "com",
eu: "eu",
in: "in",
cn: "com.cn",
jp: "jp",
au: "com.au",
} as const;
type ZohoLocation = keyof typeof LOCATION_TO_DOMAIN;
const DEFAULT_DOMAIN = "com";
function isZohoLocation(location: string): location is ZohoLocation {
return Object.prototype.hasOwnProperty.call(LOCATION_TO_DOMAIN, location);
}
export function getValidZohoDomain(location: string | undefined): string {
if (!location) return DEFAULT_DOMAIN;
return isZohoLocation(location) ? LOCATION_TO_DOMAIN[location] : DEFAULT_DOMAIN;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-store/zohocalendar/lib/zoho-domains.ts` around lines 13 - 15,
The getValidZohoDomain function currently indexes LOCATION_TO_DOMAIN with the
raw location value which allows prototype keys like "toString" to resolve
inherited properties; update getValidZohoDomain to first ensure location is a
plain string and then check membership using a safe own-property check (e.g.,
Object.prototype.hasOwnProperty.call(LOCATION_TO_DOMAIN, location) or
Object.hasOwn) before returning LOCATION_TO_DOMAIN[location]; if the check fails
return DEFAULT_DOMAIN (still allow the existing "us" default when location is
undefined). Reference getValidZohoDomain, LOCATION_TO_DOMAIN, and DEFAULT_DOMAIN
when making the change.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant