From c7d1aaae0a90b2e1be45270e2d3e68df7c288f2e Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Wed, 14 Oct 2026 18:21:36 +0400 Subject: [PATCH] =?UTF-8?q?fix(web):=20=D1=81=D0=B2=D1=8F=D0=B7=D0=B8=20?= =?UTF-8?q?=D0=B8=D0=B7=20=D0=B7=D0=B5=D1=80=D0=BA=D0=B0=D0=BB=D0=B0=20?= =?UTF-8?q?=E2=80=94=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=B6=D0=B4=D1=83=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D0=BC=D0=B8?= =?UTF-8?q?=20=D0=B2=D0=B8=D0=B4=D0=B0=20AURORA-1234=20(I-1,=20#17)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ключ из issue_link попадал в разметку карточки без проверки: строка зеркала с разметкой в target_key исполнялась на странице с токеном. Co-Authored-By: Claude Opus 5.5 --- src/jira_hub/web/links.html | 4 ++-- tests/test_api.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/jira_hub/web/links.html b/src/jira_hub/web/links.html index 9c9c262..b6ba315 100644 --- a/src/jira_hub/web/links.html +++ b/src/jira_hub/web/links.html @@ -509,7 +509,7 @@ function fromJson(text, fileName) { // снимок хаба (GET /board) → модель доски. Эпики («Фича»/Epic) — имена дорожек, не карточки; соседи по связям — обычные карточки; // вид работы — первая метка kind-*, иначе тип задачи; срок — плановая дата окончания, иначе срок исполнения; связи — только известных -// типов (LINK_TYPES) и не с эпиками; ключи из связей, которых нет в зеркале, — заглушки на дорожке «Нет в зеркале» +// типов (LINK_TYPES), между ключами вида AURORA-1234 (ключ идёт в разметку карточки) и не с эпиками; ключи из связей, которых нет в зеркале, — заглушки на дорожке «Нет в зеркале» function fromHub(snap) { const isEpic = it => /^(Фича|Epic|Эпик)$/i.test(it.issue_type || ""); const epicNames = { ...EPICS }, epics = new Set(); @@ -525,7 +525,7 @@ function fromHub(snap) { }); snap.links.forEach(l => { const type = LINK_TYPES[l.link_type]; - if (type && !epics.has(l.source) && !epics.has(l.target)) addLink(links, seen, l.source, l.target, type); + if (type && KEY_RE.test(l.source) && KEY_RE.test(l.target) && !epics.has(l.source) && !epics.has(l.target)) addLink(links, seen, l.source, l.target, type); }); const missing = addStubs(nodes, links, NOT_IN_HUB); const problems = snap.last_sync ? [] : ["в хабе ещё не было полного обновления из Jira — нажмите «Обновить из Jira»"]; diff --git a/tests/test_api.py b/tests/test_api.py index a54059a..cfd873d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -393,3 +393,4 @@ def test_page_reads_hub_and_has_no_embedded_export(): assert '"jira-hub-token"' in html and 'hubFetch("/board")' in html assert "Нет в зеркале" in html assert 'author: "viewer"' in html and "/batches/" in html + assert "KEY_RE.test(l.source) && KEY_RE.test(l.target)" in html # I-1: ключи связей из зеркала идут в разметку карточек