Skip to content

fix(customer): reject expired API tokens instead of silent renew - #396

Merged
biz87 merged 1 commit into
betafrom
fix/371-expired-api-token-no-renew
Jul 26, 2026
Merged

fix(customer): reject expired API tokens instead of silent renew#396
biz87 merged 1 commit into
betafrom
fix/371-expired-api-token-no-renew

Conversation

@Ibochkarev

Copy link
Copy Markdown
Member

Описание

Истёкший TYPE_API токен больше не продлевается с тем же string. TokenService::resolveApiToken() удаляет запись (как AuthManager::validateToken), TokenMiddleware на protected routes отвечает 401 + ms3_err_token_expired, чистит cookie и session (customer_id тоже).

Без этого утечка Bearer/cookie давала бессрочный доступ. /token/refresh (#334) — отдельный баг; здесь только reject, не rotation.

Тип изменений

  • Исправление бага (non-breaking change)

Связанные Issues

Closes #371

Как это было протестировано?

cd core/components/minishop3
php -l src/Middleware/TokenMiddleware.php
php -l src/Services/TokenService.php
php -l src/Utils/ApiTokenExpiry.php
php tests/ApiTokenExpiryPolicyTest.php
# остальные smoke:
for f in tests/*Test.php; do php "$f"; done
  • Ручное тестирование
  • Автоматические тесты (ApiTokenExpiryPolicyTest + existing smoke)
  • Тестирование на разных версиях PHP/MODX

Конфигурация тестирования:

  • MiniShop3: ветка fix/371-expired-api-token-no-renew
  • MODX: не требуется для smoke
  • PHP: 8.4 локально

Скриншоты (если применимо)

До После
n/a n/a

Чеклист

  • Код соответствует стилю проекта
  • Добавлены/обновлены комментарии в сложных местах
  • Изменения не ломают существующую функциональность
  • Лексиконы добавлены на двух языках (ru/en) — ключ ms3_err_token_expired уже был
  • PHPStan проходит без новых ошибок (локально; в CI пока нет)
  • ESLint проходит без ошибок (npm run lint:ci для Vue)
  • Обновлён CHANGELOG.md (для значимых изменений)

Дополнительные заметки

@Ibochkarev Ibochkarev added priority: high Важно исправить в ближайшее время bug Something isn't working labels Jul 16, 2026
@Ibochkarev
Ibochkarev requested a review from biz87 July 16, 2026 02:57
@Ibochkarev
Ibochkarev force-pushed the fix/371-expired-api-token-no-renew branch from 8ab734a to f120e18 Compare July 23, 2026 16:07
Align TokenMiddleware and TokenService with AuthManager: remove expired
TYPE_API tokens and return 401 so clients must refresh or log in.
@Ibochkarev
Ibochkarev force-pushed the fix/371-expired-api-token-no-renew branch from f120e18 to 89531ca Compare July 24, 2026 02:15
@biz87

biz87 commented Jul 26, 2026

Copy link
Copy Markdown
Member

Security-fix (token lifecycle) — валидировал актуальную rebase'нутую версию (89531ca): тест ApiTokenExpiryPolicyTest OK, PHPStan чист на всех 7 файлах, CI зелёный.

Закрыты две дыры:

  • Auto-renew истёкшего токена (set expires_at; save → украденный Bearer/cookie давал бессрочный доступ) → теперь remove().
  • Session bypass (при живой session customer_id токен не валидировался) → теперь наличие токена = строгая валидация всегда; clearClientTokenState() чистит и customer_id.

Разобрали влияние на корзину (по факту кода):

  • Авторизованный — корзину НЕ теряет: getDraft() fallback по customer_id перепривязывает draft к новому токену после re-login.
  • Анонимный — корзина живёт весь TTL токена (дефолт 24ч, ms3_customer_token_ttl), после expiry — новая корзина. Приемлемый баланс; при желании TTL поднимается настройкой без правки кода.

Design-граница: PHP session без токена по-прежнему допускает customer_id — это отдельный вектор (session hijacking), не в scope #371. Fix закрывает именно API-токен: украденный Bearer после expiry мёртв.

Follow-up (не блокер): working /token/refresh (#334/#351).

Для CHANGELOG: истёкший API-токен теперь reject'ится (401 ms3_err_token_expired) с очисткой cookie/session, а не молча продлевается.

Мержим.

@biz87
biz87 merged commit d801ed8 into beta Jul 26, 2026
2 checks passed
@biz87
biz87 deleted the fix/371-expired-api-token-no-renew branch July 26, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority: high Важно исправить в ближайшее время

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] TokenMiddleware: expired API-token бесконечно продлевается без ротации

2 participants