Skip to content

fix(ep-commerce): remove browser-readable EP token leak (#282)#306

Open
field123 wants to merge 4 commits into
masterfrom
feat/ep-remove-server-token-leak
Open

fix(ep-commerce): remove browser-readable EP token leak (#282)#306
field123 wants to merge 4 commits into
masterfrom
feat/ep-remove-server-token-leak

Conversation

@field123
Copy link
Copy Markdown
Collaborator

Summary

Closes #282 (parent: #279 HIGH-3). The shopper's per-session EP access
token is no longer serialized into page HTML or any browser-reachable
surface. Catalog reads now use the SDK's anonymous-mint flow client-side;
shopper-bound reads/writes route through the proxy.

This is a breaking change for any consumer using the legacy
browser-direct EP SDK hooks. See "Migration" below.

What changed

Token surface removed

  • providerProps() returns {} regardless of session state — the
    primary regression gate, asserted by a new test.
  • auth/ep-provider-server-info.ts (the bridge that piped serverToken
    into Plasmic's contexts) deleted, along with the getServerInfo: key
    on the EP commerce provider meta.
  • serverToken parameter dropped from the entire provider chain:
    registerCommerceProvider, getCommerceProvider,
    getElasticPathProvider, initElasticPathClient, plus the
    EPCommerceProvider Studio prop.
  • Example-app catchall page no longer sets
    globalContextsProps["plasmic-commerce-elastic-path-provider$dev"] = session.providerProps().

Legacy cart hooks deleted

The pre-#273 hooks built around getEPClient(provider) are removed in
favor of the proxy-backed replacements that landed in #299/#300:

  • cart/use-cart.tsx → consumers use useEpCart (SWR over getCart proxy).
  • cart/use-add-item.tsxEPAddToCartButton already uses
    callEpProxy("addCartItem", …).
  • cart/use-update-item.tsx, cart/use-remove-item.tsx → call
    callEpProxy("updateCartItem"|"removeCartItem", …) directly + invalidate
    with swrMutate(epCartCacheKey()).
  • All four cart/__tests__/use-*.test.tsx files removed.

Cart-drawer / checkout consumers migrated

  • cart-drawer/EPCartDrawer.tsx, EPCartDrawerTrigger.tsx,
    checkout/composable/EPCheckoutCartSummary.tsx: switched to
    useEpCart().
  • cart-drawer/EPCartItemRemoveButton.tsx,
    cart-drawer/EPCartItemQuantityControl.tsx: switched to inline
    callEpProxy(...) + swrMutate(epCartCacheKey()).
  • cart-drawer-components.test.tsx mock layer rewritten to mock
    useEpCart + callEpProxy directly.

Studio global cart actions preserved

registerCommerceProvider.tsx replaces upstream
CartActionsProvider (which depended on provider.cart.useAddItem etc.)
with a new in-package EpCartActionsProvider that wires the same
Studio-facing addItem/updateItem/removeItem actions through
callEpProxy. Existing Studio bindings against those global actions
continue to work without designer-side changes.

Dead auth/ep-*-server-info.ts files deleted

Three orphan files written for upstream's reverted
CodeComponentMeta.getServerInfo (PR #246, never landed) — never
imported by any production code:

  • auth/ep-product-server-info.ts
  • auth/ep-product-list-server-info.ts
  • auth/ep-related-products-server-info.ts
    …and their tests.

Migration

Replace any direct imports from @elasticpath/plasmic-ep-commerce-elastic-path/cart/use-*:

  • useCart()useEpCart() from
    @elasticpath/plasmic-ep-commerce-elastic-path (returns
    { cart, isLoading, error, refresh } instead of SWR's { data, error }).
  • useAddItem()EPAddToCartButton (which uses the proxy internally),
    or callEpProxy("addCartItem", { productId, quantity, ... }, null)
    directly.
  • useUpdateItem()callEpProxy("updateCartItem", { itemId, quantity }, null)
    • swrMutate(epCartCacheKey()).
  • useRemoveItem()callEpProxy("removeCartItem", { itemId }, null)
    • swrMutate(epCartCacheKey()).

The Studio "Add item to cart / Update item / Remove item" global actions
on the Elastic Path Provider are unchanged — they now just route through
the proxy under the hood.

Test plan

  • All 1444 jest tests + 27 vitest tests pass locally.
  • New test providerProps() never serializes the EP access token (#282)
    asserts providerProps() is {} and the JSON form does not contain
    the token.
  • cart-drawer-components.test.tsx (110 tests) verifies the migrated
    proxy + SWR call shapes.
  • Static verification: git grep confirms no production code calls
    providerProps(), no browser-reachable surface contains
    accessToken/serverToken/epAccessToken outside of explicit
    server-side bearer flows (proxy routes, ALS context, cart server
    routes).
  • Manual browser verification (please confirm during review): start
    the example app, open DevTools → Network on /, /products,
    /product/[id], /cart, and confirm no serverToken,
    accessToken, epAccessToken, or bearer-shaped string appears in
    any response body or document HTML.

Out of scope

- providerProps() returns {} regardless of session (slice 1)
- delete ep-provider-server-info.ts bridge + getServerInfo meta key (slice 2)
- drop serverToken parameter from provider chain (slice 3)

Slices 4-8 pending. Saving WIP so we can switch to PR #300 rebase.
…les + example-app leak

Slice 5: git rm three dead auth/ep-*-server-info.ts files (written for the
upstream CodeComponentMeta.getServerInfo path that was reverted in #246;
never imported by any production code) and their tests.

Slice 6: drop globalContextsProps["plasmic-commerce-elastic-path-provider$dev"]
= session.providerProps() from the example app's catchall page. providerProps()
returns {} after slice 1 anyway, so this was a no-op — explicit deletion
documents intent. Update middleware.ts comment that referenced the removed
serverToken flow.
…ers to proxy

Cart-drawer, checkout-summary, and the global cart actions (Studio
"Add/Update/Remove item" actions) all moved off the legacy
useCart/useAddItem/useRemoveItem/useUpdateItem hooks onto the proxy +
useEpCart path landed in #300:
  - EPCartDrawer / EPCartDrawerTrigger / EPCheckoutCartSummary now consume
    useEpCart() (SWR over /api/ep/proxy/[fn] getCart) instead of
    @plasmicpkgs/commerce's useCart wrapper.
  - EPCartItemRemoveButton inlines callEpProxy("removeCartItem", ...) +
    swrMutate(epCartCacheKey()).
  - EPCartItemQuantityControl inlines callEpProxy("updateCartItem"|"removeCartItem", ...).
  - registerCommerceProvider replaces upstream CartActionsProvider with a
    proxy-backed EpCartActionsProvider that wires the same Studio global
    actions (addItem/updateItem/removeItem) through callEpProxy. Studio
    designers' existing action bindings keep working.

Then deletes the legacy hooks and their tests:
  - cart/use-add-item.tsx, use-cart.tsx, use-update-item.tsx, use-remove-item.tsx
  - cart/__tests__/ for each of the above
  - cart/index.ts (only re-exported the deleted hooks)

provider.ts no longer imports them, no longer surfaces a `cart: {...}`
field on the ElasticPathProvider shape.

cart-drawer-components.test.tsx mock layer rewritten to mock useEpCart
+ callEpProxy instead of the deleted hook surface; assertions updated
to verify the proxy fn name + payload (no more location field on update —
the proxy doesn't accept it).
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.

Security: remove browser-readable EP token leak (#279 HIGH-3)

1 participant