Conversation
Replace 4 independent token storages (localStorage, $_SESSION,
ms3_customer_tokens, msCustomer.token) with single httpOnly cookie
as source of truth. Fixes cart desync after login/session expiry.
Key changes:
- CookieHelper: httpOnly cookie ms3_token using MODX session_cookie_* settings
- TokenService::resolveOrCreateToken(): unified token resolution chain
(session → cookie → generate new)
- TokenMiddleware: cookie injection into $_REQUEST for backward compat
with all controllers, Authorization: Bearer support
- Login/Register: reuse existing token instead of creating new one,
bind draft order to customer — guest cart preserved on login
- Logout: detach customer from token, keep cookie for guest cart
- Snippets: unified token resolution via resolveOrCreateToken()
- JS: remove localStorage usage, use credentials: 'same-origin'
- OrderDraftManager: add sortby('id', 'DESC') for deterministic
draft selection with multiple drafts
- Customer::autoLoginCustomer(): bind msCustomerToken to customer
and set cookie on auto-login after first order
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Review fixes: - DRY: move bindDraftToCustomer() to OrderDraftManager, remove duplicates from Login.php and Register.php - TTL: unify on ms3_customer_token_ttl (default 604800) everywhere, remove ms3_customer_api_token_ttl references - Logout: generate fresh anonymous token instead of reusing old (potentially compromised) token string - CookieHelper: add guard against duplicate Set-Cookie headers when cookie already has correct value - ms3_customer.php: remove clearTokenCookie on redirect to login (was destroying guest cart cookie) - TokenMiddleware: remove redundant cookie check in resolveToken() (cookie already injected into $_REQUEST), update docblock - auth-forms.js: clean up dead comments - Customer::autoLoginCustomer(): clarify $this->token fallback chain Co-Authored-By: Claude Opus 4.6 <[email protected]>
- CookieHelper: fix sliding expiry — static flag now actually set after setcookie() - TokenMiddleware: merge duplicate resolveToken() comments (steps 3-4 → step 3) - OrderDraftManager: add $ctx parameter to bindDraftToCustomer() for consistency Co-Authored-By: Claude Opus 4.6 <[email protected]>
- CookieHelper: bool $cookieSetInThisRequest → ?string $lastTokenSet Prevents duplicate Set-Cookie for same token, allows token change (Logout) - clearTokenCookie() resets $lastTokenSet = null - CHANGELOG: document PR #124 fix + Register.php breaking change Co-Authored-By: Claude Opus 4.6 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
$_SESSION,ms3_customer_tokens,msCustomer.token) без синхронизации. Корзина не работает после логина — добавление идёт по одному токену, отображение по другому.ms3_tokenкак единственный источник правды. Токен устанавливается сервером, отправляется браузером автоматически, недоступен из JS.$_COOKIE → $_REQUEST) обеспечивает обратную совместимость — CartController, OrderController, AuthorizedCustomerTrait работают без изменений.Changes
New
CookieHelper— управление httpOnly cookie, использует MODXsession_cookie_*настройкиTokenService::resolveOrCreateToken()— единая цепочка разрешения токена (session → cookie → generate)Customer::autoLoginCustomer()— привязкаmsCustomerTokenк customer при автологине после первого заказаModified
$_REQUEST, поддержкаAuthorization: Bearer, auto-create токена для первого визитаtokenвозвращает строку, не объект)bin2hex(random_bytes(32))). Старая гостевая корзина теряется (security: старый токен инвалидирован)$tokenService->resolveOrCreateToken()вместо дублирующейся логикиcredentials: 'same-origin'sortby('id', 'DESC')при поиске draft по customer_id,bindDraftToCustomer()с фильтром по contextNot modified (backward compat via middleware)
$_REQUEST)$_REQUEST)Register.php response format
До:
{ "token": { "token": "abc123...", "expires_at": "2026-03-09 12:00:00" } }После:
{ "token": "abc123...", "expires_at": "2026-03-09 12:00:00" }Поле
tokenтеперь возвращает строку вместо объекта. Полеexpires_atвынесено на верхний уровень. Кастомные темы/интеграции, обращающиеся кresult.object.token.token, потребуют обновления.Test plan
ms3_tokenпоявляется (httpOnly=true)ms3_tokenнет в URL-параметрах запросов🤖 Generated with Claude Code