Files
CodeNomad/packages/ui/src/lib/i18n/messages/ru/remoteAccess.ts
VooDisss f3c54df283 fix(server): show sane remote URLs for 0.0.0.0 binds (#262)
Closes #261

## Summary

- improve startup remote URL selection when the server binds to
`0.0.0.0`
- print additional reachable remote URLs instead of advertising only the
first external address
- add targeted tests for address ordering and advertisability behavior

## Problem

When CodeNomad was started with `--host 0.0.0.0`, the CLI chose the
first external IPv4 address it discovered and displayed only that one as
the remote URL.

On Windows machines with WSL, Hyper-V, Docker, or other virtual
adapters, that often surfaced a virtual `172.x.x.x` address even though
a more useful LAN address such as `192.168.x.x` was also reachable and
usable from other devices.

That made remote access look broken or confusing even though the server
itself was accessible.

## What changed

- reuse the resolved network-address list for both:
  - primary remote URL selection
  - startup logging of additional reachable URLs
- choose the primary remote URL from the **advertisable** external
addresses instead of any external address
- print `Other Accessible URLs` when multiple useful remote URLs are
available
- avoid hard-coding a preference like `192.168 > 10 > 172`
- suppress link-local `169.254.*` addresses from user-facing advertised
URLs
- add tests covering:
  - stable ordering across RFC1918 address ranges
  - link-local addresses being non-advertisable
  - link-local-first discovery not stealing the primary LAN URL

## Why this approach

This keeps address derivation in the network-address resolver layer and
limits `index.ts` to startup wiring and presentation.

It also fixes the misleading terminal output without redesigning binding
behavior, TLS behavior, or the server API contract.

## Validation

- `npm run typecheck --workspace @neuralnomads/codenomad`
- `npx tsx --test
'.\\src\\server\\__tests__\\network-addresses.test.ts'`

## Notes

- this change is intentionally focused on selection and presentation of
reachable addresses
- it does not attempt a broader virtual-adapter classification policy
beyond suppressing clearly low-value link-local addresses in user-facing
output

---------

Co-authored-by: Shantur Rathore <i@shantur.com>
2026-04-01 22:12:28 +01:00

54 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const remoteAccessMessages = {
"remoteAccess.eyebrow": "Удаленная передача управления",
"remoteAccess.title": "Подключитесь к CodeNomad удаленно",
"remoteAccess.subtitle": "Используйте адреса ниже, чтобы открыть CodeNomad с другого устройства.",
"remoteAccess.close": "Закрыть удаленный доступ",
"remoteAccess.refresh": "Обновить",
"remoteAccess.sections.listeningMode.label": "Режим прослушивания",
"remoteAccess.sections.listeningMode.help": "Разрешайте или ограничивайте удаленную передачу управления, привязываясь ко всем интерфейсам или только к localhost.",
"remoteAccess.toggle.on": "Вкл",
"remoteAccess.toggle.off": "Выкл",
"remoteAccess.toggle.title": "Разрешить подключения с других IP",
"remoteAccess.toggle.caption.all": "Привязка к 0.0.0.0",
"remoteAccess.toggle.caption.local": "Привязка к 127.0.0.1",
"remoteAccess.toggle.note": "Изменение требует перезапуска и временно остановит все активные экземпляры. Поделитесь адресами ниже после перезапуска сервера.",
"remoteAccess.listeningMode.restartConfirm.message": "Перезапустить, чтобы применить режим прослушивания? Это остановит все запущенные экземпляры.",
"remoteAccess.listeningMode.restartConfirm.title.all": "Открыть для других устройств",
"remoteAccess.listeningMode.restartConfirm.title.local": "Ограничить этим устройством",
"remoteAccess.listeningMode.restartConfirm.confirmLabel": "Перезапустить сейчас",
"remoteAccess.listeningMode.restartConfirm.cancelLabel": "Отмена",
"remoteAccess.restart.errorManual": "Не удалось перезапустить автоматически. Перезапустите приложение, чтобы применить изменение.",
"remoteAccess.sections.serverPassword.label": "Пароль сервера",
"remoteAccess.sections.serverPassword.help": "Для удаленной передачи управления требуется пароль. Установите запоминающийся пароль, чтобы разрешить вход с других устройств.",
"remoteAccess.authStatus.unavailable": "Статус аутентификации недоступен.",
"remoteAccess.username": "Имя пользователя: {username}",
"remoteAccess.password.status.set": "Для удаленного доступа установлен пароль.",
"remoteAccess.password.status.unset": "Пока не установлен запоминающийся пароль. Установите его, чтобы разрешить вход при удаленной передаче управления.",
"remoteAccess.password.actions.cancel": "Отмена",
"remoteAccess.password.actions.change": "Изменить пароль",
"remoteAccess.password.actions.set": "Установить пароль",
"remoteAccess.password.form.newPassword": "Новый пароль",
"remoteAccess.password.form.confirmPassword": "Подтвердите пароль",
"remoteAccess.password.form.placeholder": "Не менее 8 символов",
"remoteAccess.password.error.tooShort": "Пароль должен быть не короче 8 символов.",
"remoteAccess.password.error.mismatch": "Пароли не совпадают.",
"remoteAccess.password.save.saving": "Сохранение…",
"remoteAccess.password.save.label": "Сохранить пароль",
"remoteAccess.sections.addresses.label": "Доступные адреса",
"remoteAccess.sections.addresses.help": "Откройте или отсканируйте с другой машины, чтобы передать управление.",
"remoteAccess.addresses.loading": "Загрузка адресов…",
"remoteAccess.addresses.none": "Пока нет доступных адресов.",
"remoteAccess.addresses.actions.showOther": "Показать еще {count} адресов",
"remoteAccess.addresses.actions.hideOther": "Скрыть остальные адреса",
"remoteAccess.address.scope.network": "Сеть",
"remoteAccess.address.scope.loopback": "Loopback",
"remoteAccess.address.scope.internal": "Внутренний",
"remoteAccess.address.open": "Открыть",
"remoteAccess.address.showQr": "Показать QR",
"remoteAccess.address.hideQr": "Скрыть QR",
"remoteAccess.address.qrAlt": "QR для {url}",
} as const