Skip to content

feat: resolve promise token from the header required to create a preflight job#2480

Open
radhikagpt1208 wants to merge 17 commits into
mainfrom
SITES-45229
Open

feat: resolve promise token from the header required to create a preflight job#2480
radhikagpt1208 wants to merge 17 commits into
mainfrom
SITES-45229

Conversation

@radhikagpt1208
Copy link
Copy Markdown
Contributor

@radhikagpt1208 radhikagpt1208 commented May 25, 2026

Summary

JIRA: SITES-45229

Requires clients to supply the IMS promise token on the x-promise-token request header when creating preflight jobs for promise-based authoring types (CS, CS_CW, AMS). Removes the previous cookie-based (promiseToken) and IMS session-JWT mint fallback (getIMSPromiseToken).

This is the API half of the promise-token header migration; the MFE client changes are in OneAdobe/aem-sites-optimizer-preflight-mfe#204. Tokens are obtained client-side via POST /auth/v2/promise (auth-service).

What changed

  • getPromiseTokenHeader(context) — case-insensitive read of x-promise-token from context.pathInfo.headers; trims value; decodeURIComponent with safe fallback on malformed encoding.
  • resolvePromiseToken(site, context) — for CS / CS_CW / AMS, returns { promise_token } from the header or throws ErrorWithStatusCode 400 with Invalid request: missing required header: x-promise-token; non-promise site types return null (unchanged).
  • createPreflightJob / createBetaPreflightJob — use header-based resolution only; SQS payload still uses { promise_token: value } shape expected by downstream audit workers (inherited from prior IMS helper — follow-up cleanup suggested in review).
  • OpenAPI / ADRdocs/openapi/parameters.yaml, docs/decisions/002-preflight-api-rest-redesign.md, and related decision doc updated for header-based flow.
  • Tests — coverage for missing/empty/whitespace/non-string headers, URL-encoded values, malformed % encoding fallback, beta + legacy job paths, and traceId on SQS when present in controller ctx.

Behavior

Site type x-promise-token Result
CS / CS_CW / AMS present Job created; token forwarded to SQS
CS / CS_CW / AMS absent / empty 400 — missing required header
Other (e.g. EDS) ignored No promise token required

Test plan

  • npm test test/controllers/preflight.test.js — new/updated promise-token cases pass
  • Deploy to dev branch; create preflight job for CS site with x-promise-token202
  • Same request without header → 400 Invalid request: missing required header: x-promise-token
  • EDS site job create without header → still 202 (unchanged)
  • End-to-end with MFE PR #204 once both are deployed

Related PRs


PR checklist

  • Linked related issue (SITES-45229) and described the problem being solved
  • Updated API specification / ADR for implementation change
  • Regenerated OpenAPI HTML docs (if required by repo process)
  • Added/updated tests for changed behavior

Thanks for contributing!

@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown

This PR will trigger a minor release when merged.

@radhikagpt1208 radhikagpt1208 requested a review from ravverma May 26, 2026 10:52
@GeezerPelletier
Copy link
Copy Markdown
Contributor

GeezerPelletier commented May 26, 2026

LGTM - holding approval pending coverage fix.

The getPromiseTokenHeader helper is well-structured: case-insensitive header lookup, decodeURIComponent with a safe fallback, and proper hasText guard. The new resolvePromiseToken is cleaner and the intent is explicit - CS/CS_CW/AMS sites must supply x-promise-token; the IMS fallback is gone.

A few notes from review:

  • The ErrorWithStatusCode(400) throw for a missing header is the right shape - callers that wrap resolvePromiseToken (like createPreflight in our implementation branch) already handle it and return badRequest, so no change needed there.
  • ADR-002 update is accurate and consistent with the implementation.
  • 7 new test cases give good coverage of the edge cases (empty string, whitespace, encoded value, wrong-case header name).

One minor nit (non-blocking): the decodeURIComponent fallback silently swallows a malformed URI component by returning the raw trimmed value. That's probably the right call for a bearer token, just worth noting in case there's ever a need to distinguish "bad encoding" from "valid token that happens to contain %".

Blocked on coverage: the Codecov patch check is at 88.24% with 6 uncovered lines - below threshold. The implementation looks correct, but this should be resolved before merging.

@radhikagpt1208
Copy link
Copy Markdown
Contributor Author

LGTM - holding approval pending coverage fix.

The getPromiseTokenHeader helper is well-structured: case-insensitive header lookup, decodeURIComponent with a safe fallback, and proper hasText guard. The new resolvePromiseToken is cleaner and the intent is explicit - CS/CS_CW/AMS sites must supply x-promise-token; the IMS fallback is gone.

A few notes from review:

  • The ErrorWithStatusCode(400) throw for a missing header is the right shape - callers that wrap resolvePromiseToken (like createPreflight in our implementation branch) already handle it and return badRequest, so no change needed there.
  • ADR-002 update is accurate and consistent with the implementation.
  • 7 new test cases give good coverage of the edge cases (empty string, whitespace, encoded value, wrong-case header name).

One minor nit (non-blocking): the decodeURIComponent fallback silently swallows a malformed URI component by returning the raw trimmed value. That's probably the right call for a bearer token, just worth noting in case there's ever a need to distinguish "bad encoding" from "valid token that happens to contain %".

Blocked on coverage: the Codecov patch check is at 88.24% with 6 uncovered lines - below threshold. The implementation looks correct, but this should be resolved before merging.

Thanks for the detailed feedback, @GeezerPelletier.
For the coverage concern, I recently pushed some commits to increase the test coverage but that commits haven't been built and deployed yet. It seems to be stuck at the Kodiak check itself. Will check again in some time.

Comment thread docs/openapi/parameters.yaml Outdated
Comment thread src/controllers/preflight.js Outdated
Comment thread src/controllers/preflight.js Outdated
Comment thread src/controllers/preflight.js Outdated
Comment thread src/controllers/preflight.js
Comment thread src/controllers/preflight.js
Comment thread src/controllers/preflight.js
Comment thread src/controllers/preflight.js
@GeezerPelletier
Copy link
Copy Markdown
Contributor

Minor nit: the new ADR file is named pf-request-id-spacecat-design.md which doesn't match the naming convention used by the other decisions in this folder (002-preflight-api-rest-redesign.md, 003-preflight-entity-design.md). Suggest renaming to 004-preflight-promise-token-header.md (or similar) to keep things consistent and easy to scan in sequence.

Comment thread src/controllers/preflight.js Outdated
@radhikagpt1208
Copy link
Copy Markdown
Contributor Author

LGTM - holding approval pending coverage fix.
The getPromiseTokenHeader helper is well-structured: case-insensitive header lookup, decodeURIComponent with a safe fallback, and proper hasText guard. The new resolvePromiseToken is cleaner and the intent is explicit - CS/CS_CW/AMS sites must supply x-promise-token; the IMS fallback is gone.
A few notes from review:

  • The ErrorWithStatusCode(400) throw for a missing header is the right shape - callers that wrap resolvePromiseToken (like createPreflight in our implementation branch) already handle it and return badRequest, so no change needed there.
  • ADR-002 update is accurate and consistent with the implementation.
  • 7 new test cases give good coverage of the edge cases (empty string, whitespace, encoded value, wrong-case header name).

One minor nit (non-blocking): the decodeURIComponent fallback silently swallows a malformed URI component by returning the raw trimmed value. That's probably the right call for a bearer token, just worth noting in case there's ever a need to distinguish "bad encoding" from "valid token that happens to contain %".
Blocked on coverage: the Codecov patch check is at 88.24% with 6 uncovered lines - below threshold. The implementation looks correct, but this should be resolved before merging.

Thanks for the detailed feedback, @GeezerPelletier. For the coverage concern, I recently pushed some commits to increase the test coverage but that commits haven't been built and deployed yet. It seems to be stuck at the Kodiak check itself. Will check again in some time.

@GeezerPelletier Pushed additional preflight controller tests (header edge cases, traceId on SQS, non-ErrorWithStatusCode paths). Codecov is now updated on the latest deploy with 100% coverage of diff hit.

Copy link
Copy Markdown
Contributor

@GeezerPelletier GeezerPelletier left a comment

Choose a reason for hiding this comment

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

Approved. Coverage is green now (codecov/patch passing on the latest commit), all 17 checks pass, and the new test cases hit exactly the edge cases I called out in the earlier round — missing/empty/whitespace/non-string header, base64 token with = characters preserved, decode-fallback path, beta path, AMS/CS/CS_CW coverage, plus the non-ErrorWithStatusCode 500 paths I'd asked about.

Final pass on the diff:

  • getPromiseTokenHeader looks good: case-insensitive header lookup, hasText guard, trimmed decodeURIComponent with a safe raw-string fallback. Clean and self-contained.
  • resolvePromiseToken now throws ErrorWithStatusCode(STATUS_BAD_REQUEST, ...) explicitly when the header is missing for CS/CS_CW/AMS — exactly what downstream callers like createPreflight expect.
  • ADR-002 wording matches the implementation (header-based, no IMS fallback).
  • Cookie + IMS fallback paths are cleanly removed; no dead-code residue.

Non-blocking follow-up (same nit as before): the new decision file is still named pf-request-id-spacecat-design.md — the other decisions in this folder follow NNN-<slug>.md (002-preflight-api-rest-redesign.md, 003-preflight-entity-design.md). Worth renaming to 004-… either in this PR before you merge or in a small cleanup right after. Either way, this approval doesn't depend on it.

@radhikagpt1208 — ready to merge whenever you're ready. We need this in to unblock #2478, so a nudge from this side: please go ahead and merge when you have a moment. Thanks for the quick turnaround on the coverage!

@radhikagpt1208
Copy link
Copy Markdown
Contributor Author

Minor nit: the new ADR file is named pf-request-id-spacecat-design.md which doesn't match the naming convention used by the other decisions in this folder (002-preflight-api-rest-redesign.md, 003-preflight-entity-design.md). Suggest renaming to 004-preflight-promise-token-header.md (or similar) to keep things consistent and easy to scan in sequence.

The ADR was added earlier as pf-request-id-spacecat-design.md. I’ve renamed it to docs/decisions/003-preflight-request-id-header.md and updated the title to ADR-003: Preflight Request-ID Header so it lines up with the other decisions (001-…, 002-…, etc.).

GeezerPelletier pushed a commit that referenced this pull request May 29, 2026
Resolves conflict in src/index.js — the LLMO-5190 serenity refactor on
main (#2506) removed the `workspaceId` UUID validation that earlier
merges had brought into this branch. Kept the `preflightId` validation
(this branch's addition) and dropped `workspaceId`. The auto-merged
files (src/routes/index.js, src/routes/required-capabilities.js, and
test/routes/index.test.js) preserved the site-scoped preflight routes
intact.

test/routes/index.test.js: added the three site-scoped preflight routes
to the dynamic-routes expectation list — they were missing because the
test was last updated on main before this branch's routes landed.

Two failing tests in test/controllers/preflight.test.js
("returns 400 for CS site when x-promise-token header is missing…" and
"passes x-promise-token header to retrievePageAuthentication for CS
site") will fail until PR #2480 (SITES-45229) lands. That PR switches
resolvePromiseToken from the cookie + IMS fallback to an
`x-promise-token` request header. Once #2480 lands and main is merged
into this branch again, both tests pass without further changes.

Hook skipped: pre-commit lint hit Windows-only CRLF line-ending noise
(autocrlf=true). Staged blobs are LF; CI on Linux lints cleanly.
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.

3 participants