Skip to content

fix: use promise token cookie in preflight and suggestions controller#1917

Merged
radhikagpt1208 merged 10 commits intomainfrom
SITES-33748
Mar 17, 2026
Merged

fix: use promise token cookie in preflight and suggestions controller#1917
radhikagpt1208 merged 10 commits intomainfrom
SITES-33748

Conversation

@radhikagpt1208
Copy link
Copy Markdown
Contributor

@radhikagpt1208 radhikagpt1208 commented Mar 6, 2026

JIRA: https://jira.corp.adobe.com/browse/SITES-33748

Summary

Updates the preflight controller to read the promiseToken from the browser cookie (set by POST /auth/promise) instead of the x-promise-token request header or minting a new token via IMS on every request.

Problem

For promise-based authoring types (CS, CS_CW, AMS), the preflight controller previously relied on either:

  1. An x-promise-token request header (which the MFE cannot set since the cookie is HttpOnly and unreadable by JS), or
  2. Calling IMS on every request to mint a new promise token (unnecessary round-trip)

The auth/promise endpoint sets the promise token as an HttpOnly cookie via Set-Cookie. When the MFE calls POST /preflight/jobs with credentials: 'include', the browser automatically sends this cookie in the Cookie request header. The controller was never reading it.

Changes

  • src/controllers/preflight.js: Replaced x-promise-token header lookup and IMS fallback with getCookieValue(context, 'promiseToken') to read the promiseToken cookie from context.pathInfo.headers.cookie (populated by enrichPathInfo middleware). Falls back to IMS if cookie is absent.
  • test/controllers/preflight.test.js: Updated tests to reflect cookie-based token resolution - covers cookie present, cookie absent (IMS fallback), and cookie missing promiseToken key.

Dependency

Fastly VCL update required for end-to-end cookie flow

  • This PR is safe to merge on its own - the IMS fallback preserves backward compatibility. However, the cookie-based flow will not work end-to-end in deployed environments until a coordinating Fastly VCL change is made.
  • The Fastly VCL at spacecat-infrastructure/fastly/vcl/8_deliver/deliver-100-set-cors-response-headers.vcl unconditionally sets Access-Control-Allow-Origin: * for all /api/* requests, overwriting any CORS headers Lambda returns.
  • Per the Fetch spec, browsers reject credentials: 'include' responses when Access-Control-Allow-Origin is *.
  • The VCL also does not set Access-Control-Allow-Credentials: true or include Cookie in Access-Control-Allow-Headers.
  • Until the VCL is updated, the browser will not send the cookie on cross-origin POST requests. The getCookieValue() call will return null and fall through to getIMSPromiseToken().

Fastly config update for Preflight request

  • This is being tracked in SITES-41543.
  • Fastly VCL has been updated to set access-control-allow-origin to the origin and access-control-allow-credentials: true:
# set to origin if coming from preflight otherwise set to *
     if (( req.url ~ "^/api/ci/preflight/" || req.url ~ "^/api/v1/preflight/")
        && (req.http.Origin ~ "^https://experience(-qa|-stage)?\.adobe\.com$"
            || req.http.Origin ~ "^https?://localhost")) {
        set resp.http.access-control-allow-origin = req.http.Origin;
        set resp.http.access-control-allow-credentials = "true";
    } else if (!resp.http.access-control-allow-origin) {
        set resp.http.access-control-allow-origin = "*";
    }

Follow-up: Fastly config update for Suggestions request

  • Update Fastly VCL to include suggestions autofix path.
  • The current VCL regex only covers /api/ci/preflight/ and /api/v1/preflight/.
  • The suggestions autofix endpoint (/api/v1/sites/:siteId/opportunities/:opportunityId/suggestions/auto-fix) is not matched, so the cookie flow won't work for autofix until the VCL paths are expanded.
  • This will be done once UI changes are in place and tested for the e2e flow @ravverma.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 6, 2026

This PR will trigger a patch release when merged.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@ravverma
Copy link
Copy Markdown
Contributor

ravverma commented Mar 9, 2026

Hi @solaris007,
Adding a proposal to solve CORS problem , @radhikagpt1208 Please validate.

CORS for Credentialed Preflight Flow

Problem

The Preflight MFE uses credentials: 'include' for:

  • POST /auth/promise — sets HttpOnly promiseToken cookie (auth-service)
  • POST /preflight/jobs — sends that cookie (api-service)

With credentials, the browser requires:

  • Access-Control-Allow-Origin: exact requesting origin (not *)
  • Access-Control-Allow-Credentials: true

localCORSWrapper in api-service handles this when ENABLE_CORS=true, but in deployed envs this is off. API Gateway CORS returns Access-Control-Allow-Origin: *, so credentialed requests fail.


Solution Overview

Enable Lambda-based CORS in the api-service for deployed environments and align configuration across dev/stage/prod.


1. Use Lambda for CORS (Remove "Local Only")

File: src/index.js

Update the comment so CORS is not treated as local-only:

/**
 * CORS middleware wrapper for credentialed cross-origin requests.
 * When ENABLE_CORS=true, reflects the requesting origin (if allowlisted) and
 * sets Access-Control-Allow-Credentials for cookie-bearing requests.
 * Required for Preflight MFE flow (POST /auth/promise, POST /preflight/jobs).
 */

No code changes to localCORSWrapper itself — it already does origin reflection when the origin is in the allowlist.


2. Environment Configuration

Add the following to secrets/params for each environment.

dev

{
  "ENABLE_CORS": "true",
  "CORS_ALLOWED_ORIGINS": "https://preflight-dev.adobe.com,https://localhost:3000,http://localhost:3000"
}

stage

{
  "ENABLE_CORS": "true",
  "CORS_ALLOWED_ORIGINS": "https://preflight-stage.adobe.com,https://stage-preflight.example.com"
}

prod

{
  "ENABLE_CORS": "true",
  "CORS_ALLOWED_ORIGINS": "https://preflight.adobe.com"
}

Replace with the real Preflight MFE origins per environment.


3. API Gateway Configuration

Lambda responses must not be overwritten by API Gateway CORS.

  • With Lambda proxy integration, the Lambda response (including headers) is returned as-is.
  • If API Gateway is adding CORS (e.g. "Enable CORS" or gateway responses), either:
    • Disable API Gateway CORS and rely on Lambda for CORS headers, or
    • Ensure API Gateway does not add Access-Control-Allow-Origin (or uses a pass-through) so Lambda’s headers win.

Action: In the AWS console or IaC for api-service, review CORS settings and remove any Access-Control-Allow-Origin: * that would override Lambda.


4. OPTIONS Preflight Handling

Both the OPTIONS response and the actual POST response must include correct CORS headers.

API service: Requests go through localCORSWrapper before route matching. There may not be a route for OPTIONS, so:

  1. Add explicit OPTIONS handling for credentialed paths, or
  2. Ensure the main handler returns a proper response for OPTIONS on those paths.

If OPTIONS is handled by API Gateway (mock/integration), it may return *. In that case, either:

  • Route OPTIONS for /preflight/jobs (and any other credentialed paths) to Lambda so localCORSWrapper can add headers, or
  • Adjust API Gateway integration so OPTIONS uses the same Lambda as POST (if supported).

5. Include Cookie in Allowed Headers

File: src/index.jslocalCORSWrapper

Cookie must be in Access-Control-Allow-Headers for credentialed requests:

response.headers.set(
  'Access-Control-Allow-Headers',
  'Content-Type, Authorization, x-api-key, x-ims-org-id, x-client-type, x-import-api-key, '
  + 'x-trigger-audits, x-requested-with, origin, accept, Cookie, x-promise-token',
);

Add Cookie to the existing header list.


6. Cookie Path Alignment

Auth-service sets promiseToken with Path=${API_GATEWAY_PREFIX} (e.g. /api or /api/v1).

Ensure API_GATEWAY_PREFIX matches the path under which both auth- and api-service run so the cookie is sent for POST /preflight/jobs. If they use different prefixes, the cookie path must cover both.


Checklist

# Task Owner
1 Update localCORSWrapper comment Dev
2 Add ENABLE_CORS and CORS_ALLOWED_ORIGINS to dev/stage/prod secrets DevOps/Config
3 Confirm Preflight MFE origins per env Product/Frontend
4 Check API Gateway CORS config; remove * override DevOps
5 Add Cookie to Access-Control-Allow-Headers Dev
6 Verify OPTIONS for /preflight/jobs hit Lambda Dev/QA
7 Test credentialed flow (auth/promise → preflight/jobs) in each env QA

Testing

  1. From Preflight MFE origin, call POST /auth/promise with credentials: 'include' and validate promiseToken cookie.
  2. Call POST /preflight/jobs with credentials: 'include' and confirm the cookie is sent and the request succeeds.
  3. Check for CORS errors in the browser console.
  4. Verify response headers: Access-Control-Allow-Origin: <exact-origin>, Access-Control-Allow-Credentials: true.

@solaris007
Copy link
Copy Markdown
Member

@ravverma @radhikagpt1208 - the CORS solution proposed in the comment above is on the right track but there's a blocker layer that needs to be addressed first.

Fastly VCL overrides Lambda CORS headers

fastly/vcl/8_deliver/deliver-100-set-cors-response-headers.vcl runs in the deliver subroutine (after the backend response) and unconditionally overwrites all CORS headers for every /api/v1|ci|stage|prod request:

set resp.http.access-control-allow-origin = "*";
set resp.http.access-control-allow-headers = "authorization, x-api-key, ...";
// Access-Control-Allow-Credentials is never set

Even if localCORSWrapper returns a reflected origin + Access-Control-Allow-Credentials: true, Fastly replaces them before the browser sees the response. The ENABLE_CORS=true Lambda change won't help in deployed environments without a VCL change.

Two additional blockers

  1. Cookie and x-promise-token are not in the VCL's Access-Control-Allow-Headers - the browser's OPTIONS preflight will be rejected even if origin reflection is fixed
  2. Access-Control-Allow-Credentials is never set by Fastly - required for credentials: include to work

Required VCL change

fastly/vcl/8_deliver/deliver-100-set-cors-response-headers.vcl needs to reflect the origin conditionally:

if (req.url ~ "^/api/v1" || req.url ~ "^/api/ci" || req.url ~ "^/api/stage" || req.url ~ "^/api/prod") {
    set resp.http.access-control-allow-methods = "GET, HEAD, PATCH, POST, PUT, OPTIONS, DELETE";
    set resp.http.access-control-allow-headers = "authorization, x-api-key, x-import-api-key, origin, x-requested-with, content-type, accept, x-trigger-audits, x-promise-token, cookie";

    if (req.http.Origin ~ "preflight.*\.adobe\.com" || req.http.Origin ~ "^https?://localhost") {
        set resp.http.access-control-allow-origin = req.http.Origin;
        set resp.http.access-control-allow-credentials = "true";
    } else {
        set resp.http.access-control-allow-origin = "*";
    }
}

The exact origin regex needs to be updated with the real Preflight MFE origins per environment. The Lambda-side changes (ENABLE_CORS=true, CORS_ALLOWED_ORIGINS) are still worth doing for local dev consistency but won't unblock the deployed environments on their own.

@radhikagpt1208
Copy link
Copy Markdown
Contributor Author

@ravverma @radhikagpt1208 - the CORS solution proposed in the comment above is on the right track but there's a blocker layer that needs to be addressed first.

Fastly VCL overrides Lambda CORS headers

fastly/vcl/8_deliver/deliver-100-set-cors-response-headers.vcl runs in the deliver subroutine (after the backend response) and unconditionally overwrites all CORS headers for every /api/v1|ci|stage|prod request:

set resp.http.access-control-allow-origin = "*";
set resp.http.access-control-allow-headers = "authorization, x-api-key, ...";
// Access-Control-Allow-Credentials is never set

Even if localCORSWrapper returns a reflected origin + Access-Control-Allow-Credentials: true, Fastly replaces them before the browser sees the response. The ENABLE_CORS=true Lambda change won't help in deployed environments without a VCL change.

Two additional blockers

  1. Cookie and x-promise-token are not in the VCL's Access-Control-Allow-Headers - the browser's OPTIONS preflight will be rejected even if origin reflection is fixed
  2. Access-Control-Allow-Credentials is never set by Fastly - required for credentials: include to work

Required VCL change

fastly/vcl/8_deliver/deliver-100-set-cors-response-headers.vcl needs to reflect the origin conditionally:

if (req.url ~ "^/api/v1" || req.url ~ "^/api/ci" || req.url ~ "^/api/stage" || req.url ~ "^/api/prod") {
    set resp.http.access-control-allow-methods = "GET, HEAD, PATCH, POST, PUT, OPTIONS, DELETE";
    set resp.http.access-control-allow-headers = "authorization, x-api-key, x-import-api-key, origin, x-requested-with, content-type, accept, x-trigger-audits, x-promise-token, cookie";

    if (req.http.Origin ~ "preflight.*\.adobe\.com" || req.http.Origin ~ "^https?://localhost") {
        set resp.http.access-control-allow-origin = req.http.Origin;
        set resp.http.access-control-allow-credentials = "true";
    } else {
        set resp.http.access-control-allow-origin = "*";
    }
}

The exact origin regex needs to be updated with the real Preflight MFE origins per environment. The Lambda-side changes (ENABLE_CORS=true, CORS_ALLOWED_ORIGINS) are still worth doing for local dev consistency but won't unblock the deployed environments on their own.

Thanks for the detailed explanation, @solaris007 @ravverma.
I've created a ticket here to track this. We can first update the config for dev, test it e2e and then replicate the same for prod.

@radhikagpt1208 radhikagpt1208 requested a review from ravverma March 16, 2026 09:32
Copy link
Copy Markdown
Contributor

@ravverma ravverma left a comment

Choose a reason for hiding this comment

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

Hey @radhikagpt1208,

changes looks clean , some points need to be addressed before merge


Must Fix

getCookieValue is not exported from @adobe/spacecat-shared-http-utils

The import resolves to undefined at runtime — getCookieValue is not in the package's public index. Only authWrapper, s2sAuthWrapper, enrichPathInfo, hashWithSHA256, and the four auth handlers are exported. This means the cookie is never read and every request silently falls through to IMS, making the change a no-op.

Approach: Implement getCookieValue locally in src/support/utils.js and import from there, or confirm a new version of the shared package exports it and bump the dependency.


Should Fix

JSDoc still describes the old x-promise-token header behaviour

The method-level comment and the @param for context.pathInfo.headers still reference x-promise-token. Update both to describe the promiseToken cookie source and the IMS fallback.


Minor

Check if hasText import is still needed

If the if (hasText(headerToken)) guard is fully removed, verify hasText is still used elsewhere in the file — if not, remove it from the import to keep things clean.

Copy link
Copy Markdown
Contributor

@ravverma ravverma left a comment

Choose a reason for hiding this comment

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

Need to address some changes

@ravverma ravverma added the tech debt Technical Debt label Mar 16, 2026
Copy link
Copy Markdown
Member

@solaris007 solaris007 left a comment

Choose a reason for hiding this comment

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

Hey @radhikagpt1208,

Strengths

  • The architectural direction is correct - moving from the x-promise-token header to the HttpOnly cookie that /auth/promise already sets. The MFE cannot programmatically read an HttpOnly cookie to forward it as a header, so the old design had a gap. This closes it by relying on the browser's credentials: 'include' behavior.
  • Cookie name is consistent between writer and reader: auth-service sets promiseToken=... at promise.js:153, and this PR reads getCookieValue(context, 'promiseToken'). Names match exactly.
  • The IMS fallback is preserved, maintaining backward compatibility for non-browser callers.
  • Test coverage is solid for the three core scenarios: cookie present (skips IMS), cookie absent (falls back to IMS), and other cookies present without promiseToken (falls back to IMS).

Issues

Critical (Must Fix)

1. Deep internal import bypasses package public API - src/controllers/preflight.js:20

import { getCookieValue } from '@adobe/spacecat-shared-http-utils/src/auth/handlers/utils/cookie.js';

getCookieValue is not exported from @adobe/spacecat-shared-http-utils's public API (src/index.js). The package has "main": "src/index.js" and no exports map, so Node resolves the deep path at runtime, but this couples the service to the internal file layout of a shared library. Any refactor of that internal structure will silently break this import at deploy time. The shared library team has no visibility that an external consumer depends on this path.

Fix: Either (a) add getCookieValue to the shared package's public exports and bump the version, or (b) write a trivial local cookie parser in src/support/utils.js - it's ~5 lines.

2. Cookie value truncation for tokens containing = - @adobe/spacecat-shared-http-utils/src/auth/handlers/utils/cookie.js:40

const [cookieName, cookieValue] = cookie.trim().split('=');

split('=') splits on ALL = characters, but destructuring only captures the first two elements. If the promise token contains = (common in base64 or JWT padding, e.g., promiseToken=eyJ...Q==), the value is silently truncated - eyJ...Q instead of eyJ...Q==. The truncated token will fail when used for AEM authoring operations.

This is especially relevant here because auth-service calls getPromiseToken(accessToken, true) with encryption enabled (promise.js:75), making it likely the token contains = padding.

Fix: If writing a local parser (per issue #1), use indexOf('=') + substring:

const idx = cookie.indexOf('=');
const name = cookie.substring(0, idx).trim();
const value = cookie.substring(idx + 1).trim();

If keeping the shared utility, file a bug against spacecat-shared-http-utils and fix line 40 before merge.

Important (Should Fix)

3. Fastly VCL will block this flow in deployed environments

The Fastly VCL at spacecat-infrastructure/fastly/vcl/8_deliver/deliver-100-set-cors-response-headers.vcl unconditionally sets Access-Control-Allow-Origin: * for all /api/* requests, overwriting any headers Lambda returns. Per the Fetch spec, browsers reject credentials: 'include' responses when Access-Control-Allow-Origin is *. The VCL also does not set Access-Control-Allow-Credentials: true or include Cookie in Access-Control-Allow-Headers.

This means the browser will never send the cookie on the cross-origin POST. The getCookieValue() call returns null, falling through to getIMSPromiseToken(), which requires an Authorization header the MFE may not send.

This isn't a blocker for merging the Lambda-side change, but it needs a coordinating VCL update before the feature works end-to-end. Consider adding a note in the PR description about this dependency.

4. Suggestions controller still uses x-promise-token header - src/controllers/suggestions.js:1074-1077

The suggestions controller has the same x-promise-token header pattern. This PR only changes preflight.js, creating divergence between two endpoints that share identical promise-token semantics. If the intent is to move to cookies, both controllers should be updated together or as a coordinated pair.

5. No test for cookie values containing = - test/controllers/preflight.test.js

All tests use promiseToken=promiseToken123 - a value with no =. Add a test with a realistic token format (e.g., promiseToken=eyJhbGci...sig==) to verify the full value is preserved through the parsing pipeline.

Minor (Nice to Have)

6. JSDoc partially updated - src/controllers/preflight.js:89-97

The description mentions the cookie now, but @param for context.pathInfo.headers says (including cookie) which is vague. Could be more specific about the promiseToken cookie expectation.

Recommendations

  1. The cleanest path: add getCookieValue to spacecat-shared-http-utils's public exports, fix the split('=') bug while there, publish a patch, then import from the clean public path here. Two small PRs.
  2. If the shared package change is blocked: write a local getCookieValue(context, name) in src/support/utils.js with correct = handling.
  3. Verify in a deployed environment that the cookie path/scope set by auth-service (Path=${apiGatewayPrefix}) covers the /preflight/jobs endpoint.
  4. Confirm the encrypted promise token format - if it never contains =, the truncation bug is not a blocker, but it should still be fixed in the shared utility.

Assessment

Not ready to merge. The deep internal import (Critical #1) must be resolved. The = truncation risk (Critical #2) needs verification against the actual token format and likely a fix. The Fastly CORS blocker (Important #3) needs a coordinating VCL change before the feature works end-to-end in deployed environments.

radhikagpt1208 and others added 2 commits March 16, 2026 20:58
…stions controllers

Replace deep internal import of getCookieValue from spacecat-shared-http-utils
with a local implementation in src/support/utils.js that uses indexOf-based
splitting to correctly handle cookie values containing '=' (base64/JWT tokens).
Also migrate suggestions controller from x-promise-token header to cookie-based
resolution for consistency with the preflight controller.
@radhikagpt1208
Copy link
Copy Markdown
Contributor Author

@ravverma, looks like you reviewed a previous version of the PR:

  1. JSDoc still describes the old x-promise-token header behaviour:

This was already updated in the PR. The method description now references the promiseToken cookie and the @param for headers says "must include a cookie header with promiseToken=<token> for CS/CS_CW/AMS authoring types" (line 99). There are no remaining references to x-promise-token in the JSDoc for preflight controller.

  1. if (hasText(headerToken)) guard is fully removed, verify hasText is still used elsewhere in the file — if not, remove it from the import to keep things clean.

hasText import is still needed. The old hasText(headerToken) was already replaced with hasText(cookieToken) on line 144, so the import is still actively used.

@solaris007,

  1. Fastly VCL will block this flow in deployed environments

Acknowledged. This PR is safe to merge on its own since the IMS fallback preserves backward compatibility. The coordinating VCL change is tracked in SITES-41543 and has already been updated.

  1. Suggestions controller still uses x-promise-token header

Fixed. Updated src/controllers/suggestions.js to use getCookieValue(context, 'promiseToken') instead of pathInfo.headers['x-promise-token'], keeping both controllers consistent. JSDoc and tests updated accordingly.

  1. No test for cookie values containing =

Added. test/controllers/preflight.test.js now includes a test with a realistic base64 token (eyJhbGciOiJSUzI1NiJ9...dGVzdHNpZw==) that verifies the full value is preserved through the parsing pipeline.

  1. JSDoc partially updated

Fixed. The @param for context.pathInfo.headers now reads: "must include a cookie header with promiseToken= for CS/CS_CW/AMS authoring types" in both preflight and suggestions controllers.

Common comment:

getCookieValue local utility:

  • Removed the deep import from @adobe/spacecat-shared-http-utils/src/auth/handlers/utils/cookie.js and added a local getCookieValue(context, name) in src/support/utils.js.
  • The local getCookieValue uses indexOf('=') + substring() instead of split('=') with destructuring, so values like eyJ...Q== are preserved in full.
  • This avoids coupling to the shared package's internal file layout and fixes the split('=') truncation bug present in @adobe/spacecat-shared-http-utils/src/auth/handlers/utils/cookie.js:40.
  • Added unit tests in test/support/utils.test.js that verify base64 tokens with = padding, multiple = characters, and cookies with = in values
  • Added 7 unit tests covering: basic lookup, missing cookie, missing headers, base64 values with =, multiple = padding, multiple cookies with = in values, and empty cookie string.

@radhikagpt1208 radhikagpt1208 changed the title fix: using promise token cookie in preflight controller fix: use promise token cookie in preflight and suggestions controller Mar 16, 2026
Copy link
Copy Markdown
Member

@solaris007 solaris007 left a comment

Choose a reason for hiding this comment

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

Hey @radhikagpt1208,

Thanks for the thorough updates - all six findings from our prior review are addressed.

Prior Issues - All Resolved

# Finding Status
1 Critical - Deep internal import Fixed - local getCookieValue in src/support/utils.js
2 Critical - Cookie value truncation on = Fixed - indexOf-based parsing preserves base64 padding
3 Important - Fastly VCL blocker Addressed - documented in PR description, tracked in SITES-41543
4 Important - Suggestions controller divergence Fixed - suggestions.js now uses identical cookie pattern
5 Important - No test for = values Fixed - base64 test in preflight + 7 unit tests for getCookieValue
6 Minor - JSDoc Fixed - updated in both controllers

Strengths

  • The local getCookieValue implementation is clean and correctly handles all edge cases (= in values, missing cookies, empty strings). Well-tested with 7 unit tests plus integration coverage.
  • Both controllers now use the identical pattern, keeping the codebase consistent.
  • The IMS fallback guarantees zero behavioral change until the VCL dependency ships - safe to merge independently.
  • Fastly VCL dependency is clearly documented in the PR description with the actual VCL snippet and SITES-41543 tracking link.

Issues

Minor (Nice to Have)

1. Orphaned JSDoc block - src/support/utils.js:622-631

The getCookieValue function was inserted between getIMSPromiseToken's JSDoc block (ending at line 631) and its function definition (line 660+). This leaves getIMSPromiseToken's @returns/@throws documentation orphaned, and the function itself undocumented. Move getCookieValue above the getIMSPromiseToken JSDoc block, or move the JSDoc back down to sit directly above its function.

Recommendations

  1. Follow-up: Update SITES-41543 VCL to include suggestions autofix path. The current VCL regex only covers /api/ci/preflight/ and /api/v1/preflight/. The suggestions autofix endpoint (/api/v1/sites/:siteId/opportunities/:opportunityId/suggestions/auto-fix) is not matched, so the cookie flow won't work for autofix until the VCL paths are expanded.
  2. Follow-up: File issue to fix getCookieValue truncation bug in @adobe/spacecat-shared-http-utils. The JWT handler uses the shared package's version for sessionToken - same split('=') bug exists there.

Assessment

Ready to merge. All prior critical and important issues are resolved. The local cookie parser is correct and well-tested. Backward compatibility is preserved via IMS fallback. The minor JSDoc placement issue can be fixed in a follow-up.

@radhikagpt1208 radhikagpt1208 merged commit ef3feb3 into main Mar 17, 2026
8 of 9 checks passed
@radhikagpt1208 radhikagpt1208 deleted the SITES-33748 branch March 17, 2026 08:41
solaris007 pushed a commit that referenced this pull request Mar 17, 2026
## [1.351.3](v1.351.2...v1.351.3) (2026-03-17)

### Bug Fixes

* use promise token cookie in preflight and suggestions controller ([#1917](#1917)) ([ef3feb3](ef3feb3))
@solaris007
Copy link
Copy Markdown
Member

🎉 This PR is included in version 1.351.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

released tech debt Technical Debt

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants