Skip to content

Adding encrypted INCY links - #53

Closed
densds wants to merge 2 commits into
remnawave:devfrom
densds:dev
Closed

Adding encrypted INCY links#53
densds wants to merge 2 commits into
remnawave:devfrom
densds:dev

Conversation

@densds

@densds densds commented Jul 18, 2026

Copy link
Copy Markdown

Moved subscription encryption from the backend to the frontend, modified the original INCY library, and now all logic is moved to the frontend without public API endpoints

@greptile-apps

This comment was marked as outdated.

Comment thread frontend/src/widgets/main/installation-guide/installation-guide.connector.tsx Outdated
Comment thread frontend/package.json Outdated
@densds

This comment was marked as outdated.

@Pinkerton28

Copy link
Copy Markdown

Hi @densds, the blocker on this PR just went away.

INCY published an official browser build: @incy/link-encoder 1.2.0 now ships a /web entry point built on Web Crypto (crypto.subtle) instead of node:crypto, so the fork is no longer needed.

It keeps the same function names, the same wire format and the same { name } option as the Node entry (the library truncates n to 128 chars on its own), and it is Promise-based, which is exactly how the useEffect here already calls it. So the change looks like one import plus one dependency swap:

-import { encryptLink } from '@densds/link-encoder'
+import { encryptLink } from '@incy/link-encoder/web'

Some context: I asked INCY for a browser build on their feedback board (https://feedback.incy.cc/issues/cmt4zocxi003w4sam3txk9izj). They shipped it within the hour and asked whether someone could help land the Remnawave side.

Happy to help and to test it on a live INCY deployment. If you would rather not touch this PR, just say so and I will open one, with credit to your work here.

@densds

densds commented Aug 23, 2026

Copy link
Copy Markdown
Author

Hi @Pinkerton28, the dependencies have been updated, they now link to the official package from the INCY team, tested on my server, all functions work

@densds

This comment was marked as resolved.

@Pinkerton28

Copy link
Copy Markdown

@densds nice, that was fast.

Confirming from a live deployment: we shipped the same library today (1.2.0, /web entry) in three separate frontends against a production INCY user base: a Remnawave subscription page, our own web cabinet, and a Telegram mini app. crypt1 imports work on iOS, Android and desktop. Cross-checked the format too: links encrypted in the browser decrypt back correctly with the Node entry.

@kastov

kastov commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Боюсь, что данная реализация не может принята.

Конкретно этот PR затрагивает вещи/файлы, которые ему фактически не нужны, например включение обязательной подгрузки Telegram JS SDK.

Для так называемых Template Variables, коим и являются INCY_CRYPT1_LINK и HAPP_CRYPT4_LINK, есть специальное место, в котором они обрабатываются и заменяются:
https://github.com/remnawave/subscription-page/blob/dev/frontend/src/shared/utils/template-engine.ts#L12-L25

Проблема вот в чем – Incy реализовал энкрипт через асинхронный WebCrypto, что накладывает мягко скажем некоторые ограничения. iOS/Safari очень плохо переваривает асинхронные клики, поэтому сам "движок по замене" асинхронным делать нельзя.

Так что, даже не знаю... есть предложения?

@Pinkerton28

Copy link
Copy Markdown

Есть вариант, у нас он уже крутится в проде.

Движок оставляем синхронным, асинхронность просто убирается из клика. crypt1 считается один раз заранее, как только известен subscriptionUrl, и кладётся в модульный кеш. Ленивая функция потом читает готовое:

INCY_CRYPT1_LINK: () =>
    incyCrypt.get(metaInfo.subscriptionUrl) ?? `incy://add/${metaInfo.subscriptionUrl}`

Если значение ещё не готово или WebCrypto недоступен (http, старый вебвью), подставится обычная incy://add/<url>, её приложение принимает точно так же. Кнопка рабочая в любой момент, а в обработчике клика нет ни одного await, так что на iOS/Safari ничего не меняется. Шифрование там миллисекунды, к первому клику значение давно готово.

По файлам трогается только template-engine.ts плюс маленький модуль с кешем. Ни Telegram SDK, ни docker-compose, ни index.html.

Мы это выкатили сегодня в трёх местах на живых пользователях: страница подписки, свой веб-кабинет и мини-аппа в телеге. iOS, Android, десктоп, импорт везде проходит.

Второй вариант, если хочется полной симметрии с HAPP_CRYPT: попросить INCY выпустить синхронный вход на чистом JS, как jsencrypt в cryptohapp. Тогда кеш не нужен вообще, будет такая же однострочная ленивая функция. Спросить могу я, мы с ними уже переписываемся: браузерную сборку они выпустили через час после нашей просьбы.

Скажите, какой путь ближе, и пришлю минимальный PR.

@kastov

kastov commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Синхронный вариант, конечно, был бы предпочтительнее. Давайте попробуем попросить. Вариант с "прогревом" оставим на запаску пока что.

"@remnawave/subscription-page-types": "0.5.1" – заодно можете бампнуть на фронтенде версию, там теперь INCY_CRYPT1_LINK будет доступен в Template Variables.

Adds an INCY_CRYPT1_LINK template placeholder for INCY deep links
(incy://crypt1/...), alongside the existing HAPP_CRYPT3_LINK/HAPP_CRYPT4_LINK
support for Happ. Encryption runs entirely client-side via the official
@incy/link-encoder/web (Web Crypto) build, using the already-loaded,
already-validated subscription info — no backend endpoint involved.

Split out from remnawave#53 at the maintainer's request, dropping the unrelated
Telegram WebView / docker-compose / index.html changes so this PR only
covers the INCY feature itself.
0.5.1 registers INCY_CRYPT1_LINK as a recognized Template Variable
(SUBSCRIPTION_PAGE_TEMPLATE_KEYS / TSubscriptionPageTemplateKey) so the
panel's button-link picker can offer it alongside HAPP_CRYPT3_LINK /
HAPP_CRYPT4_LINK. Per maintainer request on remnawave#53. No code changes needed —
diffed 0.5.0 vs 0.5.1 directly, the only change in the package is this
constant.
@densds

densds commented Aug 23, 2026

Copy link
Copy Markdown
Author

Убрал лишние изменения в diff, как только или если incy сделают библиотеку синхронной то смогу обновить
@greptile-apps re-review

@LLC-INCY

LLC-INCY commented Aug 23, 2026

Copy link
Copy Markdown

@densds @kastov сделали библиотеку синхронной

@Pinkerton28

Copy link
Copy Markdown

@kastov Как уже было сказано выше, выпущен синхронный вход, @incy/link-encoder 1.3.0, точка ./sync. Внутри @noble/ciphers (MIT, без зависимостей от WebCrypto), то есть работает и в браузере, и синхронно.

Все проверено: возвращает строку сразу, не промис, формат байт в байт совпадает с node и web входами, ссылки читаются между всеми тремя.

Получается, в template-engine.ts это ложится одной строкой, ровно как ключи Happ:

INCY_CRYPT1_LINK: () => encryptLink(metaInfo.subscriptionUrl, { name: '' })

Ни прогрева, ни кеша, ни асинхронности в обработчике клика.

Могу прислать PR: импорт, одна строка в движке и бамп версии пакета. Скажите, нужно ли, или сделаете сами.

@kastov

kastov commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

50f078b

Релиз на днях.

@kastov kastov closed this Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants