Repository navigation
Conversation
Ядро:
- Декомпозиция Bot.ts на делегаты в src/core/utils/ (WebhookServer, UserQueues,
DeliveryDedup, PollingRunner, FormWizard, ShutdownSignals, actions, menu,
outbound, http, promise, errors); явные списки экспортов вместо `export *`;
graceful shutdown без принудительного exit; memory-сессии per-platform.
- ReDoS-валидатор: неоднозначные разбиения строки — пары опциональных атомов
((?:a?b?)+, 868 мс на 41 символе), «сцепленный» одиночный атом
((?:\d\d?)+, числа Фибоначчи, 40 цифр ~20 с), фиксированный {n>=10};
(a?)+, (?:ab?)+, IP-паттерны остаются разрешёнными.
- Prototype pollution: ключи __proto__ из payload не попадают в данные
defineAction, mergeRow FileAdapter и normalizedHeaders webhookEvent.
- Падение процесса и «зависший» ответ на исключении из responseCb
(sync-бросок, async-отклонение, отказ до отправки) — защитная отправка
ответа по умолчанию + .catch на промисе обработчика вебхук-сервера.
- Приоритет реального payload над setContent(); memory-сессия выдаётся
поверхностной копией (гонка параллельных запросов одного пользователя).
БД:
- FileAdapter применяет query.rules (обрезка ключа/значения по max) и
возвращает пустую выборку без error (контракт _select: error = «данные
не загрузились» — раньше валил сохранение userData на обычном промахе);
update мержит поля, не затирая отсутствующие (паритет с Mongo).
- Base.save: upsert-ретрай при отклонённом insert (гонка select→insert
больше не теряет правки); Mongo: дедуп конкурентных connect().
- saveData/saveDataSync не пишут содержимое таблицы в error.log.
Адаптеры:
- Опции alisa_skill_id / smartapp_application_id: отклонение чужого
трафика на URL вебхука (HTTP 401; opt-in, без опции поведение прежнее).
- Пустой userId Алисы → '' (как в Marusia); random_id VK через
crypto.randomInt; temp-файл TTS через randomUUID.
CLI:
- mode из flow.json игнорируется — всегда strict_prod (недоверенный вход
не понижает безопасность сгенерированного бота).
- extractHttpSecrets сканирует фрагмент URL (в т.ч. без query); секретные
значения с {{var}} предупреждают о литеральной части в генерате.
- Валидатор: типы response.*/card.images, {{__proto__}}, итеративный DFS
по всем компонентам графа; генерация блокируется ошибкой валидации.
- Own-check lookup-таблиц (SYSTEM_VARS, TOKEN_ENV_NAMES, PLATFORM_README,
PLATFORMS); маскирование токена в ошибках webhook; .env с правами 0600
и проверкой .gitignore; валидация имени env в deploy.js; санитизация
doc.name в README.
Производительность:
- ipFilter: предпарсинг CIDR-правил в фабрике (−1,2–2,3 мкс на запрос,
было +135% к стоимости запроса); кэш blockNeedsAsync (WeakMap) —
генерация flow из тысяч блоков без квадратичных обходов.
Документация: CHANGELOG (3.1.7), platform-integration.md (доверие к payload
платформ без подписи), configuration.md/dbAdapter.md (FileAdapter и публичные
боты; контракт адаптеров), json-format.md (mode), cli/AGENTS.md (закрытые
баги генератора), platform-contracts.md (x-marusia-signature — только детект).
Тесты: +30 регрессионных (1942 passed, 128 сьютов), защита от дублирующихся
реэкспортов и snapshot публичного API в CI.
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce4fe15353
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Если задан whitelist — должен быть match | ||
| if (whitelist && whitelist.length) { | ||
| const matched = whitelist.some((cidr) => ipInCidr(ip, cidr)); | ||
| if (whitelistRules && whitelistRules.length) { |
There was a problem hiding this comment.
Keep invalid whitelists fail-closed
When a nonempty whitelist contains only invalid entries, such as ['192.0.2.0/33'], toRules() drops every entry and this condition skips whitelist enforcement entirely. Requests from every IP then reach next(), whereas the previous implementation rejected them because none matched. Preserve the distinction between an absent/empty whitelist and a configured whitelist with no valid rules, or reject invalid configuration at middleware creation.
Useful? React with 👍 / 👎.
| }) | ||
| .join('&'); | ||
| action.url = action.url.slice(0, queryStart + 1) + query + action.url.slice(end); | ||
| let newUrl = action.url.slice(0, queryStart + 1); |
There was a problem hiding this comment.
Preserve the URL prefix when only a fragment is present
For an HTTP action URL containing # but no ?, queryStart is -1, so this initializes newUrl with slice(0, 0) and discards the entire scheme, host, and path. For example, https://api.example.com/hooks#section becomes #section; the generated Node.js fetchWithTimeout() call consequently receives a relative URL and fails instead of executing the action. Initialize the prefix through hashIndex when there is no query string, and assert the complete generated URL in the fragment-only regression test.
AGENTS.md reference: cli/AGENTS.md:L125-L126
Useful? React with 👍 / 👎.
Ядро:
- Декомпозиция Bot.ts на делегаты в src/core/utils/ (WebhookServer, UserQueues,
DeliveryDedup, PollingRunner, FormWizard, ShutdownSignals, actions, menu,
outbound, http, promise, errors); явные списки экспортов вместо `export *`;
graceful shutdown без принудительного exit; memory-сессии per-platform.
- ReDoS-валидатор: неоднозначные разбиения строки — пары опциональных атомов
((?:a?b?)+, 868 мс на 41 символе), «сцепленный» одиночный атом
((?:\d\d?)+, числа Фибоначчи, 40 цифр ~20 с), фиксированный {n>=10};
(a?)+, (?:ab?)+, IP-паттерны остаются разрешёнными.
- Prototype pollution: ключи __proto__ из payload не попадают в данные
defineAction, mergeRow FileAdapter и normalizedHeaders webhookEvent.
- Падение процесса и «зависший» ответ на исключении из responseCb
(sync-бросок, async-отклонение, отказ до отправки) — защитная отправка
ответа по умолчанию + .catch на промисе обработчика вебхук-сервера.
- Приоритет реального payload над setContent(); memory-сессия выдаётся
поверхностной копией (гонка параллельных запросов одного пользователя).
БД:
- FileAdapter применяет query.rules (обрезка ключа/значения по max) и
возвращает пустую выборку без error (контракт _select: error = «данные
не загрузились» — раньше валил сохранение userData на обычном промахе);
update мержит поля, не затирая отсутствующие (паритет с Mongo).
- Base.save: upsert-ретрай при отклонённом insert (гонка select→insert
больше не теряет правки); Mongo: дедуп конкурентных connect().
- saveData/saveDataSync не пишут содержимое таблицы в error.log.
Адаптеры:
- Опции alisa_skill_id / smartapp_application_id: отклонение чужого
трафика на URL вебхука (HTTP 401; opt-in, без опции поведение прежнее).
- Пустой userId Алисы → '' (как в Marusia); random_id VK через
crypto.randomInt; temp-файл TTS через randomUUID.
CLI:
- mode из flow.json игнорируется — всегда strict_prod (недоверенный вход
не понижает безопасность сгенерированного бота).
- extractHttpSecrets сканирует фрагмент URL (в т.ч. без query); секретные
значения с {{var}} предупреждают о литеральной части в генерате.
- Валидатор: типы response.*/card.images, {{__proto__}}, итеративный DFS
по всем компонентам графа; генерация блокируется ошибкой валидации.
- Own-check lookup-таблиц (SYSTEM_VARS, TOKEN_ENV_NAMES, PLATFORM_README,
PLATFORMS); маскирование токена в ошибках webhook; .env с правами 0600
и проверкой .gitignore; валидация имени env в deploy.js; санитизация
doc.name в README.
Производительность:
- ipFilter: предпарсинг CIDR-правил в фабрике (−1,2–2,3 мкс на запрос,
было +135% к стоимости запроса); кэш blockNeedsAsync (WeakMap) —
генерация flow из тысяч блоков без квадратичных обходов.
Документация: CHANGELOG (3.1.7), platform-integration.md (доверие к payload
платформ без подписи), configuration.md/dbAdapter.md (FileAdapter и публичные
боты; контракт адаптеров), json-format.md (mode), cli/AGENTS.md (закрытые
баги генератора), platform-contracts.md (x-marusia-signature — только детект).
Тесты: +30 регрессионных (1942 passed, 128 сьютов), защита от дублирующихся
реэкспортов и snapshot публичного API в CI.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80764a526d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (typeof value === 'string') { | ||
| // Без эллипсиса: хранимое значение — чистый префикс, «…» | ||
| // испортил бы ключ строки и JSON в поле data. | ||
| element[field] = Text.resize(value, rule.max, false); |
There was a problem hiding this comment.
Keep primary-key normalization consistent across reads and writes
When a string primary key exceeds its model rule's max, the new write path truncates it, but _select() and _remove() still use the original, untruncated key. For example, inserting a UsersData row with a 251-character user ID succeeds, yet selecting it with that same ID returns { status: false } because the stored ID has been shortened to 250 characters. Subsequent requests therefore cannot reload their saved state, and deletion by the original ID cannot remove it. Apply a consistent key policy across all operations, or reject oversized keys rather than silently changing their identity.
Useful? React with 👍 / 👎.
Ядро:
- Декомпозиция Bot.ts на делегаты в src/core/utils/ (WebhookServer, UserQueues,
DeliveryDedup, PollingRunner, FormWizard, ShutdownSignals, actions, menu,
outbound, http, promise, errors); явные списки экспортов вместо `export *`;
graceful shutdown без принудительного exit; memory-сессии per-platform.
- ReDoS-валидатор: неоднозначные разбиения строки — пары опциональных атомов
((?:a?b?)+, 868 мс на 41 символе), «сцепленный» одиночный атом
((?:\d\d?)+, числа Фибоначчи, 40 цифр ~20 с), фиксированный {n>=10};
(a?)+, (?:ab?)+, IP-паттерны остаются разрешёнными.
- Prototype pollution: ключи __proto__ из payload не попадают в данные
defineAction, mergeRow FileAdapter и normalizedHeaders webhookEvent.
- Падение процесса и «зависший» ответ на исключении из responseCb
(sync-бросок, async-отклонение, отказ до отправки) — защитная отправка
ответа по умолчанию + .catch на промисе обработчика вебхук-сервера.
- Приоритет реального payload над setContent(); memory-сессия выдаётся
поверхностной копией (гонка параллельных запросов одного пользователя).
БД:
- FileAdapter применяет query.rules (обрезка ключа/значения по max) и
возвращает пустую выборку без error (контракт _select: error = «данные
не загрузились» — раньше валил сохранение userData на обычном промахе);
update мержит поля, не затирая отсутствующие (паритет с Mongo).
- Base.save: upsert-ретрай при отклонённом insert (гонка select→insert
больше не теряет правки); Mongo: дедуп конкурентных connect().
- saveData/saveDataSync не пишут содержимое таблицы в error.log.
Адаптеры:
- Опции alisa_skill_id / smartapp_application_id: отклонение чужого
трафика на URL вебхука (HTTP 401; opt-in, без опции поведение прежнее).
- Пустой userId Алисы → '' (как в Marusia); random_id VK через
crypto.randomInt; temp-файл TTS через randomUUID.
CLI:
- mode из flow.json игнорируется — всегда strict_prod (недоверенный вход
не понижает безопасность сгенерированного бота).
- extractHttpSecrets сканирует фрагмент URL (в т.ч. без query); секретные
значения с {{var}} предупреждают о литеральной части в генерате.
- Валидатор: типы response.*/card.images, {{__proto__}}, итеративный DFS
по всем компонентам графа; генерация блокируется ошибкой валидации.
- Own-check lookup-таблиц (SYSTEM_VARS, TOKEN_ENV_NAMES, PLATFORM_README,
PLATFORMS); маскирование токена в ошибках webhook; .env с правами 0600
и проверкой .gitignore; валидация имени env в deploy.js; санитизация
doc.name в README.
Производительность:
- ipFilter: предпарсинг CIDR-правил в фабрике (−1,2–2,3 мкс на запрос,
было +135% к стоимости запроса); кэш blockNeedsAsync (WeakMap) —
генерация flow из тысяч блоков без квадратичных обходов.
Документация: CHANGELOG (3.1.7), platform-integration.md (доверие к payload
платформ без подписи), configuration.md/dbAdapter.md (FileAdapter и публичные
боты; контракт адаптеров), json-format.md (mode), cli/AGENTS.md (закрытые
баги генератора), platform-contracts.md (x-marusia-signature — только детект).
Тесты: +30 регрессионных (1942 passed, 128 сьютов), защита от дублирующихся
реэкспортов и snapshot публичного API в CI.
Ядро:
export *; graceful shutdown без принудительного exit; memory-сессии per-platform.