Skip to content

fix: safe env var parsing, error handling, localStorage validation, and hook fixes - #29823

Closed
PedroHenrique0713 wants to merge 5 commits into
calcom:mainfrom
PedroHenrique0713:fix/env-parse-and-error-safety
Closed

fix: safe env var parsing, error handling, localStorage validation, and hook fixes#29823
PedroHenrique0713 wants to merge 5 commits into
calcom:mainfrom
PedroHenrique0713:fix/env-parse-and-error-safety

Conversation

@PedroHenrique0713

Copy link
Copy Markdown

Summary

Six bug fixes across Cal.diy libraries and hooks.

# File Bug
1 constants.ts JSON.parse on ALLOWED_HOSTNAMES/RESERVED_SUBDOMAINS at module level crashed app at startup
2 errors.ts Redundant !response.ok && (status < 200 || status >= 300) — same as !response.ok
3 recentImpersonations.ts Corrupted localStorage (non-array) caused .filter() crash
4 getIP.ts isIpInBanListString lacked try/catch that sibling isIpInBanlist had
5 useInViewObserver.ts root: null was treated as document.body instead of viewport
6 useCompatSearchParams.ts || replaced empty string "" with "" (no-op); should use ??

fix(text): truncateOnWord now respects its maxLength parameter instead of using hardcoded 148
fix(CalEventParser): getProviderName handles empty location strings without crashing
fix(csvUtils): protect against CSV formula injection (=, +, -, @ prefixes) per OWASP guidance
fix(extract-base-email): handle emails missing @ sign without returning 'local@undefined'
fix(getBookingResponsesSchema): avoid mutating input array with in-place sort

All fixes include tests that fail before the change and pass after.
fix(text): guard against lastIndexOf returning -1 when no space in text
  truncateOnWord previously called substring(0, -1) which produces empty
  string when no space character exists within maxLength.

fix(getBookingResponsesSchema): compare against sorted copy, not original
  The previous fix created a copy for sorting but still compared items
  against the unsorted emails array, potentially missing duplicates.

fix(csvUtils.test): remove stale tests from unmerged PR calcom#29783
  The \r handling and MIME type tests belonged to PR calcom#29783 which has
  not been merged. Keep only formula injection tests from this PR.
…y improvements

fix(jsonUtils): validJson now accepts all valid JSON types (string, number,
  boolean, null, array), not just objects. Previously rejected valid JSON per
  RFC 8259 ("hello", 42, true, null, []) by requiring typeof === "object".

fix(formatPhoneNumber): wrap parsePhoneNumberWithError in try/catch.
  libphonenumber-js throws NOT_A_NUMBER error on unrecognized input,
  previously uncaught causing unhandled exception.

fix(safeStringify): return placeholder string instead of raw object on
  circular reference. Callers expect a string return type; returning the
  raw object could cause downstream TypeError on string operations.

fix(contructEmailFromPhoneNumber): add null guard. phoneNumber.replace()
  throws TypeError on null/undefined input.
…ixes

fix(hashedLinksUtils): isLinkExpired now checks BOTH expiry time AND usage count.
  Previously short-circuited on expiresAt and never reached the usage check.

fix(getIP): wrap JSON.parse and banlist validation in try/catch.
  Invalid IP_BANLIST env variable crashed server on every IP check.

fix(intervalTree): sort nodes by start time before building tree.
  Unsorted split broke interval tree search invariants (O(n) vs O(log n+k)).

fix(timezone): guard against labels without closing parenthesis.
  label.split(') ')[1] was undefined when label had no ')', crashing render.

fix(getSafeRedirectUrl): wrap new URL() in try/catch for config constants.
  Misconfigured CONSOLE_URL/WEBAPP_URL/WEBSITE_URL crashed redirect handler.
fix(constants): wrap ALLOWED_HOSTNAMES/RESERVED_SUBDOMAINS JSON.parse in
  try/catch with CSV fallback. Invalid env vars crashed the app at startup
  as module-level top-level code.

fix(errors): remove redundant condition in handleErrorsJson.
  response.ok already means status 200-299; the extra check added nothing
  and the gzip path still bypasses status checks.

fix(recentImpersonations): validate localStorage result is Array.
  Corrupt localStorage returning non-array caused .filter() crash in
  addRecentImpersonation.

fix(getIP): wrap isIpInBanListString JSON.parse in try/catch.
  Sister function isIpInBanlist was already guarded; this one had no
  protection against malformed IP_BANLIST env var.
@github-actions

Copy link
Copy Markdown
Contributor

Welcome to Cal.diy, @PedroHenrique0713! Thanks for opening this pull request.

A few things to keep in mind:

  • This is Cal.diy, not Cal.com. Cal.diy is a community-driven, fully open-source fork of Cal.com licensed under MIT. Your changes here will be part of Cal.diy — they will not be deployed to the Cal.com production app.
  • Please review our Contributing Guidelines if you haven't already.
  • Make sure your PR title follows the Conventional Commits format.

A maintainer will review your PR soon. Thanks for contributing!

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Shared utilities now defensively handle malformed environment values, IP ban lists, redirects, JSON, stringification, and missing inputs. Provider-name, email, phone-number, text, timezone, interval-tree, hashed-link, search-parameter, observer, and booking-response behavior were updated. CSV sanitization now prefixes spreadsheet formula values, with tests covering escaping and serialization. New tests cover provider-name parsing, email normalization, CSV handling, and word-boundary truncation.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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
Title check ✅ Passed The title is concise and matches the main theme of the PR: safety fixes across env parsing, error handling, localStorage validation, and hooks.
Description check ✅ Passed The description is clearly related to the changeset and accurately covers several of the listed bug fixes.
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.

Warning

⚠️ This pull request shows signs of AI-generated slop (redundant_comments, description_diff_mismatch). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/lib/csvUtils.ts (1)

54-65: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Prevent formula injection before CSV escaping and cover it end to end.

sanitizeValue currently returns before applying formula protection for values containing CSV-special characters, and the tests do not exercise those paths.

  • packages/lib/csvUtils.ts#L54-L65: prefix formula-leading values before quote/comma/newline escaping.
  • packages/lib/csvUtils.test.ts#L29-L34: add formula cases containing commas, newlines, and quotes.
  • packages/lib/csvUtils.test.ts#L43-L51: add an objectsToCsv integration case with a formula-leading field containing a CSV-special character.
🤖 Prompt for 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.

In `@packages/lib/csvUtils.ts` around lines 54 - 65, Update sanitizeValue in
packages/lib/csvUtils.ts (lines 54-65) to apply formula-prefix protection before
CSV-special-character escaping, preserving correct quoting for values containing
commas, newlines, or quotes. Add corresponding formula cases in
packages/lib/csvUtils.test.ts (lines 29-34) for each special-character path, and
add an objectsToCsv integration case at lines 43-51 using a formula-leading
field with a CSV-special character.
🧹 Nitpick comments (5)
packages/lib/csvUtils.test.ts (2)

43-51: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Cover formula sanitization through objectsToCsv.

Add a formula-leading field containing a comma or quote and assert the serialized CSV contains the prefixed single quote. This verifies the mitigation at the export boundary, not only through sanitizeValue.

🤖 Prompt for 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.

In `@packages/lib/csvUtils.test.ts` around lines 43 - 51, Extend the objectsToCsv
test to include a formula-leading field whose value also contains a comma or
quote, then assert the serialized CSV prefixes that field with a single quote
and applies normal CSV escaping. Keep the existing newline coverage intact and
verify sanitization through objectsToCsv rather than only sanitizeValue.

29-34: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add regression cases for formula values with CSV-special characters.

The current formula tests all take the direct sanitization path, so they would pass despite the implementation bug. Add cases where formula-leading values also contain commas, newlines, and quotes.

🤖 Prompt for 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.

In `@packages/lib/csvUtils.test.ts` around lines 29 - 34, Add regression
assertions to the existing “prefixes formula-trigger characters” test in
csvUtils.test.ts for values beginning with “=”, “+”, “-”, or “@” that also
contain commas, newlines, and double quotes. Verify sanitization preserves the
CSV-special characters while prefixing the formula value with a single quote and
applying the expected CSV escaping.
packages/lib/text.test.ts (1)

7-15: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the word-boundary result, not only its length.

The current assertions would also pass if truncation happened at an arbitrary character. Add a deterministic case that verifies the last complete word is selected.

Suggested test
+    it("should truncate at the last complete word within maxLength", () => {
+      expect(truncateOnWord("the quick brown fox", 12)).toBe("the quick...");
+    });
🤖 Prompt for 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.

In `@packages/lib/text.test.ts` around lines 7 - 15, Add an explicit
expected-output assertion to the test around truncateOnWord, using deterministic
input that confirms truncation ends at the last complete word boundary rather
than merely satisfying the length limits. Preserve the existing maxLength
coverage for both 158 and 100.
packages/lib/text.ts (1)

10-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep comments focused on why, not what.

Lines 10 and 13-14 narrate the implementation rather than explaining its rationale. Rephrase them to describe the bounded candidate and the preference for a complete word.

Proposed comment cleanup
-  // First split on maxLength chars
+  // Bound the candidate before adding the optional ellipsis.
   let truncatedText = text.substring(0, maxLength);

-  // Then split on the last space, this way we split on the last word,
-  // which looks just a bit nicer.
+  // Prefer a complete word when a boundary is available.
   const lastSpaceIndex = truncatedText.lastIndexOf(" ");
🤖 Prompt for 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.

In `@packages/lib/text.ts` around lines 10 - 17, Update the comments surrounding
the truncatedText and lastSpaceIndex logic to explain the rationale rather than
narrate the operations: describe limiting the candidate to maxLength and
preferring a complete word boundary. Leave the truncation behavior and
identifiers unchanged.

Source: Coding guidelines

packages/lib/intervalTree.ts (1)

35-40: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Sort once instead of re-sorting every subtree.

This fixes the ordering bug, but each recursive call now performs another sort, making construction O(n log² n). Sort the input once in the constructor and let buildTree operate on already-sorted slices.

Proposed refactor
 constructor(nodes: IntervalNode<T>[]) {
-  this.root = this.buildTree([...nodes]);
+  this.root = this.buildTree([...nodes].sort((a, b) => a.start - b.start));
 }

 private buildTree(nodes: IntervalNode<T>[]): IntervalNode<T> | undefined {
   if (nodes.length === 0) return undefined;

-  const sorted = [...nodes].sort((a, b) => a.start - b.start);
-  const mid = Math.floor(sorted.length / 2);
-  const node = sorted[mid];
+  const mid = Math.floor(nodes.length / 2);
+  const node = nodes[mid];

-  const leftNodes = sorted.slice(0, mid);
-  const rightNodes = sorted.slice(mid + 1);
+  const leftNodes = nodes.slice(0, mid);
+  const rightNodes = nodes.slice(mid + 1);
🤖 Prompt for 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.

In `@packages/lib/intervalTree.ts` around lines 35 - 40, Move the interval-node
sorting out of the recursive buildTree flow and perform it once in the
constructor before the initial build. Update buildTree to consume already-sorted
node slices while preserving the existing midpoint selection and left/right
partitioning, so recursive construction avoids repeated sorting.
🤖 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 `@packages/lib/constants.ts`:
- Around line 140-150: Update safeParseCsvEnvVar to parse envVar directly,
accept the JSON result only when it is an array containing strings, and
otherwise use the existing comma-separated fallback. Preserve trimming and quote
removal in the fallback while ensuring the returned value always satisfies
string[].

In `@packages/lib/getIP.ts`:
- Around line 40-45: Update the IP banlist initialization around
banlistSchema.parse and both error-handling paths so malformed IP_BANLIST never
produces an empty fail-open ban list. Validate and surface the configuration
error during startup, or reuse a cached last-known-good ban list; avoid
reparsing and logging the same invalid configuration on every invocation.

In `@packages/lib/jsonUtils.ts`:
- Around line 1-7: Update validJson so parse failures cannot be confused with
valid falsy JSON values such as false, 0, or null; use undefined or a tagged
result for failure, or restore the prior object-only contract. Preserve
returning successfully parsed JSON values without treating them as invalid.

In `@packages/lib/recentImpersonations.ts`:
- Around line 23-27: Update the recent impersonation filtering flow around
getRecentImpersonations so malformed array entries such as null cannot cause
item.username to throw. Sanitize the records in the getter or apply a type guard
before the filter, while preserving valid entries and the existing username
comparison behavior.

---

Outside diff comments:
In `@packages/lib/csvUtils.ts`:
- Around line 54-65: Update sanitizeValue in packages/lib/csvUtils.ts (lines
54-65) to apply formula-prefix protection before CSV-special-character escaping,
preserving correct quoting for values containing commas, newlines, or quotes.
Add corresponding formula cases in packages/lib/csvUtils.test.ts (lines 29-34)
for each special-character path, and add an objectsToCsv integration case at
lines 43-51 using a formula-leading field with a CSV-special character.

---

Nitpick comments:
In `@packages/lib/csvUtils.test.ts`:
- Around line 43-51: Extend the objectsToCsv test to include a formula-leading
field whose value also contains a comma or quote, then assert the serialized CSV
prefixes that field with a single quote and applies normal CSV escaping. Keep
the existing newline coverage intact and verify sanitization through
objectsToCsv rather than only sanitizeValue.
- Around line 29-34: Add regression assertions to the existing “prefixes
formula-trigger characters” test in csvUtils.test.ts for values beginning with
“=”, “+”, “-”, or “@” that also contain commas, newlines, and double quotes.
Verify sanitization preserves the CSV-special characters while prefixing the
formula value with a single quote and applying the expected CSV escaping.

In `@packages/lib/intervalTree.ts`:
- Around line 35-40: Move the interval-node sorting out of the recursive
buildTree flow and perform it once in the constructor before the initial build.
Update buildTree to consume already-sorted node slices while preserving the
existing midpoint selection and left/right partitioning, so recursive
construction avoids repeated sorting.

In `@packages/lib/text.test.ts`:
- Around line 7-15: Add an explicit expected-output assertion to the test around
truncateOnWord, using deterministic input that confirms truncation ends at the
last complete word boundary rather than merely satisfying the length limits.
Preserve the existing maxLength coverage for both 158 and 100.

In `@packages/lib/text.ts`:
- Around line 10-17: Update the comments surrounding the truncatedText and
lastSpaceIndex logic to explain the rationale rather than narrate the
operations: describe limiting the candidate to maxLength and preferring a
complete word boundary. Leave the truncation behavior and identifiers unchanged.
🪄 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 Plus

Run ID: 372529ae-3019-4c67-a5ef-c3ca581c4a55

📥 Commits

Reviewing files that changed from the base of the PR and between 3894f37 and 39096ef.

📒 Files selected for processing (23)
  • packages/features/bookings/lib/getBookingResponsesSchema.ts
  • packages/lib/CalEventParser.test.ts
  • packages/lib/CalEventParser.ts
  • packages/lib/constants.ts
  • packages/lib/contructEmailFromPhoneNumber.ts
  • packages/lib/csvUtils.test.ts
  • packages/lib/csvUtils.ts
  • packages/lib/errors.ts
  • packages/lib/extract-base-email.test.ts
  • packages/lib/extract-base-email.ts
  • packages/lib/formatPhoneNumber.ts
  • packages/lib/getIP.ts
  • packages/lib/getSafeRedirectUrl.ts
  • packages/lib/hashedLinksUtils.ts
  • packages/lib/hooks/useCompatSearchParams.ts
  • packages/lib/hooks/useInViewObserver.ts
  • packages/lib/intervalTree.ts
  • packages/lib/jsonUtils.ts
  • packages/lib/recentImpersonations.ts
  • packages/lib/safeStringify.ts
  • packages/lib/text.test.ts
  • packages/lib/text.ts
  • packages/lib/timezone.ts

Comment thread packages/lib/constants.ts
Comment on lines +140 to +150
const safeParseCsvEnvVar = (envVar: string | undefined): string[] => {
if (!envVar) return [];
try {
return JSON.parse(`[${envVar}]`);
} catch {
return envVar.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
}
};

export const ALLOWED_HOSTNAMES = safeParseCsvEnvVar(process.env.ALLOWED_HOSTNAMES);
export const RESERVED_SUBDOMAINS = safeParseCsvEnvVar(process.env.RESERVED_SUBDOMAINS);

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Parse the environment value itself and validate the result.

Wrapping the value in brackets makes valid JSON arrays become nested arrays (["a"][["a"]]), while JSON.parse can also return non-string values despite the string[] annotation. Parse envVar directly, accept only arrays of strings, then use the CSV fallback.

Proposed fix
 const safeParseCsvEnvVar = (envVar: string | undefined): string[] => {
   if (!envVar) return [];
   try {
-    return JSON.parse(`[${envVar}]`);
+    const parsed: unknown = JSON.parse(envVar);
+    if (Array.isArray(parsed) && parsed.every((value) => typeof value === "string")) {
+      return parsed;
+    }
   } catch {
-    return envVar.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
   }
+  return envVar.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
 };
📝 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
const safeParseCsvEnvVar = (envVar: string | undefined): string[] => {
if (!envVar) return [];
try {
return JSON.parse(`[${envVar}]`);
} catch {
return envVar.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
}
};
export const ALLOWED_HOSTNAMES = safeParseCsvEnvVar(process.env.ALLOWED_HOSTNAMES);
export const RESERVED_SUBDOMAINS = safeParseCsvEnvVar(process.env.RESERVED_SUBDOMAINS);
const safeParseCsvEnvVar = (envVar: string | undefined): string[] => {
if (!envVar) return [];
try {
const parsed: unknown = JSON.parse(envVar);
if (Array.isArray(parsed) && parsed.every((value) => typeof value === "string")) {
return parsed;
}
} catch {
}
return envVar.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
};
export const ALLOWED_HOSTNAMES = safeParseCsvEnvVar(process.env.ALLOWED_HOSTNAMES);
export const RESERVED_SUBDOMAINS = safeParseCsvEnvVar(process.env.RESERVED_SUBDOMAINS);
🤖 Prompt for 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.

In `@packages/lib/constants.ts` around lines 140 - 150, Update safeParseCsvEnvVar
to parse envVar directly, accept the JSON result only when it is an array
containing strings, and otherwise use the existing comma-separated fallback.
Preserve trimming and quote removal in the fallback while ensuring the returned
value always satisfies string[].

Comment thread packages/lib/getIP.ts
Comment on lines +40 to +45
let banList: string[] = [];
try {
banList = banlistSchema.parse(JSON.parse(rawBanListJson));
} catch {
logger.error("Invalid IP_BANLIST JSON; treating as empty banlist");
}

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.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Do not fail open when IP_BANLIST is malformed.

Both catch blocks leave banList empty, so an invalid security configuration disables all IP bans. The invalid value is also reparsed and logged on every invocation. Validate this configuration at startup and surface the misconfiguration, or retain a last-known-good list instead of silently treating it as no bans.

Also applies to: 55-60

🤖 Prompt for 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.

In `@packages/lib/getIP.ts` around lines 40 - 45, Update the IP banlist
initialization around banlistSchema.parse and both error-handling paths so
malformed IP_BANLIST never produces an empty fail-open ban list. Validate and
surface the configuration error during startup, or reuse a cached
last-known-good ban list; avoid reparsing and logging the same invalid
configuration on every invocation.

Comment thread packages/lib/jsonUtils.ts
Comment on lines 1 to 7
export const validJson = (jsonString: string) => {
try {
const o = JSON.parse(jsonString);
if (o && typeof o === "object") {
return o;
}
return JSON.parse(jsonString);
} catch (e) {
console.log("Invalid JSON:", e);
return false;
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use an unambiguous parse-failure result.

After accepting every JSON type, validJson("false") returns the same false sentinel as malformed JSON; "0" and "null" are also falsy. Return a tagged result or use undefined for failure, or retain the previous object-only contract.

🤖 Prompt for 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.

In `@packages/lib/jsonUtils.ts` around lines 1 - 7, Update validJson so parse
failures cannot be confused with valid falsy JSON values such as false, 0, or
null; use undefined or a tagged result for failure, or restore the prior
object-only contract. Preserve returning successfully parsed JSON values without
treating them as invalid.

Comment on lines 23 to 27
const recent = getRecentImpersonations();
if (!Array.isArray(recent)) return;
const username = usernameRaw.trim().toLowerCase();
if (!username) return;
const filtered = recent.filter((item) => item.username !== username);

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate array entries before filtering.

getRecentImpersonations() returns raw parsed data, so [null] passes the new array check and item.username then throws. The outer catch silently discards the new impersonation. Validate or sanitize each record in the getter, or use a type guard before filtering.

🤖 Prompt for 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.

In `@packages/lib/recentImpersonations.ts` around lines 23 - 27, Update the recent
impersonation filtering flow around getRecentImpersonations so malformed array
entries such as null cannot cause item.username to throw. Sanitize the records
in the getter or apply a type guard before the filter, while preserving valid
entries and the existing username comparison behavior.

@PedroHenrique0713

Copy link
Copy Markdown
Author

Closing this one. I opened a stack of PRs in this repo today and, because each branch was cut from the previous one instead of from the base, they overlap: this PR carries the commits of the earlier ones as well. I am consolidating the work in #29820 and will resubmit the remaining fixes individually, on top of the base branch, once that one has been reviewed. Sorry for the noise.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant