Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions vtex/loaders/orders/orderplaced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,37 @@ interface Props {
orderId: string;
}

/**
* Checkout cookies (CheckoutDataAccess + Vtex_CHKO_Auth) are set by VTEX right
* after an order is placed and are sufficient — and preferred — to access the
* order-placed page. The VtexIdclientAutCookie_* auth cookie can still be
* present in the browser even after it has expired, so sending it alongside the
* checkout cookies (or on its own when stale) causes the request to fail.
* Strategy: use checkout cookies when available; fall back to the auth cookie
* only when they are absent.
*/
function resolveOrderCookie(headers: Headers): string {
const all = getCookies(headers);

const checkoutCookies = Object.fromEntries(
Object.entries(all).filter(([key]) =>
key === CHECKOUT_DATA_ACCESS_COOKIE || key === VTEX_CHKO_AUTH
),
);

if (Object.keys(checkoutCookies).length > 0) {

@cubic-dev-ai cubic-dev-ai Bot Apr 1, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: This condition passes when only one of the two required checkout cookies (CheckoutDataAccess, Vtex_CHKO_Auth) is present, skipping the auth-cookie fallback. Since VTEX requires both checkout cookies to grant access, a partial set will still cause the request to fail. Check that both cookies are present before choosing checkout-cookie mode.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At vtex/loaders/orders/orderplaced.ts, line 32:

<comment>This condition passes when only one of the two required checkout cookies (`CheckoutDataAccess`, `Vtex_CHKO_Auth`) is present, skipping the auth-cookie fallback. Since VTEX requires both checkout cookies to grant access, a partial set will still cause the request to fail. Check that both cookies are present before choosing checkout-cookie mode.</comment>

<file context>
@@ -11,6 +11,37 @@ interface Props {
+    ),
+  );
+
+  if (Object.keys(checkoutCookies).length > 0) {
+    return stringify(checkoutCookies);
+  }
</file context>
Suggested change
if (Object.keys(checkoutCookies).length > 0) {
const hasBothCheckoutCookies =
checkoutCookies[CHECKOUT_DATA_ACCESS_COOKIE] != null &&
checkoutCookies[VTEX_CHKO_AUTH] != null;
if (hasBothCheckoutCookies) {
Fix with Cubic

return stringify(checkoutCookies);
}
Comment on lines +32 to +34

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

Require both checkout cookies before choosing checkout-cookie mode.

At Line 32, the condition > 0 treats a partial set as valid. If only one of CheckoutDataAccess or Vtex_CHKO_Auth is present, the loader skips auth fallback and can still fail access.

Suggested fix
-  if (Object.keys(checkoutCookies).length > 0) {
+  const hasBothCheckoutCookies =
+    checkoutCookies[CHECKOUT_DATA_ACCESS_COOKIE] != null &&
+    checkoutCookies[VTEX_CHKO_AUTH] != null;
+
+  if (hasBothCheckoutCookies) {
     return stringify(checkoutCookies);
   }
📝 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
if (Object.keys(checkoutCookies).length > 0) {
return stringify(checkoutCookies);
}
const hasBothCheckoutCookies =
checkoutCookies[CHECKOUT_DATA_ACCESS_COOKIE] != null &&
checkoutCookies[VTEX_CHKO_AUTH] != null;
if (hasBothCheckoutCookies) {
return stringify(checkoutCookies);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vtex/loaders/orders/orderplaced.ts` around lines 32 - 34, The current check
returns checkout-cookie mode when any cookie exists; change the condition in the
orderplaced loader to require both cookies (specifically ensure
CheckoutDataAccess and Vtex_CHKO_Auth are present on checkoutCookies) before
returning stringify(checkoutCookies); otherwise fall through to the auth
fallback path. Locate the block that uses checkoutCookies and replace the
Object.keys(checkoutCookies).length > 0 check with an explicit presence check
for checkoutCookies.CheckoutDataAccess && checkoutCookies.Vtex_CHKO_Auth so
partial cookie sets no longer short-circuit authentication.


const authCookies = Object.fromEntries(
Object.entries(all).filter(([key]) =>
key.startsWith(VTEX_ID_CLIENT_COOKIE)
),
);

return stringify(authCookies);
}
Comment on lines +42 to +43

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 | 🟡 Minor

Avoid sending an empty cookie header when no eligible cookies exist.

If neither checkout nor auth cookies are found, resolveOrderCookie returns "" and Line 55 still forwards it. Prefer returning undefined and omitting the header entirely.

Suggested fix
-function resolveOrderCookie(headers: Headers): string {
+function resolveOrderCookie(headers: Headers): string | undefined {
   const all = getCookies(headers);
@@
-  return stringify(authCookies);
+  return Object.keys(authCookies).length > 0 ? stringify(authCookies) : undefined;
 }
@@
-  const cookie = resolveOrderCookie(req.headers);
+  const cookie = resolveOrderCookie(req.headers);
+  const headers = cookie ? { cookie } : undefined;
@@
-      }, {
-        headers: { cookie },
-      }).then((res) => res.json());
+      }, {
+        headers,
+      }).then((res) => res.json());
@@
-  }, {
-    headers: { cookie },
-  }).then((res) => res.json());
+  }, {
+    headers,
+  }).then((res) => res.json());

Also applies to: 55-55

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vtex/loaders/orders/orderplaced.ts` around lines 42 - 43, The
resolveOrderCookie function currently returns an empty string when no eligible
cookies are found, causing an empty "cookie" header to be forwarded; change
resolveOrderCookie to return undefined instead of "" when no cookies are
present, and update the caller that forwards the header (the code that sets the
"cookie" request/header using the return of resolveOrderCookie) to only add the
"cookie" header when the value is !== undefined (i.e., guard the header
assignment so it is omitted entirely when resolveOrderCookie returns undefined).


/**
* @title Get Order Placed Order Details
* @description Should be used on order placed page, the user must be authenticated or have access to the order through permissions or cookies
Expand All @@ -21,16 +52,7 @@ export default async function loader(
ctx: AppContext,
) {
const { vcsDeprecated } = ctx;
const cookies = Object.fromEntries(
Object.entries(getCookies(req.headers)).filter(([key]) =>
key.startsWith(VTEX_ID_CLIENT_COOKIE) ||
// these two cookies are set by VTEX after order is placed on checkout and are
// used to access the order placed page
key === CHECKOUT_DATA_ACCESS_COOKIE ||
key === VTEX_CHKO_AUTH
),
);
const cookie = stringify(cookies);
const cookie = resolveOrderCookie(req.headers);

const isOrderGroup = !orderId.includes("-");

Expand Down
Loading