From 87ecf3b5caa9322bf0ccbb32fd1269f5f8bd0c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 14 Aug 2026 09:36:14 +0400 Subject: [PATCH] =?UTF-8?q?HISTORY:=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20Q&A=20=D1=81=20Sonnet=20=D0=BF=D0=BE=20ema?= =?UTF-8?q?il-=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B8=D1=87=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY/2026-08-14-session-log.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/HISTORY/2026-08-14-session-log.md b/HISTORY/2026-08-14-session-log.md index c68df88..e3608db 100644 --- a/HISTORY/2026-08-14-session-log.md +++ b/HISTORY/2026-08-14-session-log.md @@ -173,3 +173,30 @@ digest `sha256:b4d1dccda75a67e1a5db3887576e1112993d6485504e683d0fa82a2374bca99b` `admin auth billing conf gosqs interfaces metrics models persistence router tenant ui utils`. `app/` не тронут (проверено: rootHandler на месте, app/ui/static и info.html целы). Оставлено: app, cmd, doc, Dockerfile, go.mod, go.sum, HISTORY, Makefile, README.md, secrets. + +--- + +## Архитектурный разбор (Claude Sonnet) — переход идентичности на email (14.08.2026) + +**Запрос к Sonnet**: файлы только `app/auth/jwt.go`, `app/tenant/tenant_store.go`, `app/admin/admin.go`, +`app/gosqs/tenant_helpers.go`, `app/persistence/redis.go`, `app/cmd/goaws.go`, +`app/auth/auth_middleware.go`, `app/ui/index.html`. + +**Ответ Sonnet (выводы)**: +1. Сломается: `TenantIDFromSub()` в jwt.go; вызов в `jwtAuth` (admin.go ~236); `access_key/secret_key` + в ответе jwtAuth; `GetBySub` в `jwtMiddleware` (~288); `bySub` → `byEmail` в TenantStore + (NewTenantStore, CreateFromJWT, Delete, LoadTenant, GetBySub). +2. Пересчёт легаси при 0 очередях безопасен, но ОБЯЗАТЕЛЬНО: удалить старый тенант из Redis + (`ssq:tenants` по старому ID) и сохранить новый — иначе после рестарта старые рандомные ключи оживут. + Весь пересчёт — под `s.mu.Lock()`. +3. Детерминированные функции — в jwt.go; byEmail-индекс — в tenant_store.go; LoadTenant индексирует + по Email только при `Email != ""` (защита от коллизии `byEmail[""]` с демо-тенантом CreateFixed). +4. Дыра — orphan AccessKey в byAccessKey: при пересчёте удалять из byAccessKey ДО добавления нового. +5. Критичное неучтённое: (a) email может быть пустым → проверка в jwtAuth (400), не в ParseJWTClaims; + (b) QueueUrl содержит TenantID — при смене ID URL меняется, у клиентов захардкоженные URL сломаются + (сейчас очередей нет — не критично); (c) демо-тенант без Email не должен попадать в byEmail. + +**Решение (принято)**: все пункты включаем в v0.1.28. Токен — только аутентификация; +email из JWT детерминированно задаёт TenantID/AccessKey/SecretKey; рандома нет; +ключи на экране не светятся — только по кнопке в модалке с подсказкой; +`POST /ui/api/auth` перестаёт отдавать ключи; новый `GET /ui/api/credentials` под JWT-сессией.