# Ловушка 1. Приложению нужно публичное имя раньше, чем первая строчка кода

## Почему `localhost` не работает

Вход в W3DS устроен так: человек подтверждает вход **в кошельке на телефоне**, и кошелёк
после этого сам обращается к приложению по сети — отправляет подписанные данные.

`http://localhost:3006` — это адрес «на этом же компьютере». С телефона он указывает
на сам телефон. Кошелёк постучится в пустоту, приложение никогда не узнает, что человек
подтвердил вход, и на экране навсегда останется «ждём подтверждения».

Это не настраивается и не обходится. **Нужен адрес, доступный из интернета.**

## Решение на время разработки: туннель

Туннель — программа, которая делает ваш локальный порт доступным по публичному адресу.

### Cloudflare (рекомендуется: не нужен аккаунт)

Установка:

| Система | Команда |
|---|---|
| macOS | `brew install cloudflared` |
| Windows | `winget install --id Cloudflare.cloudflared` |
| Linux (deb) | скачать пакет с `https://github.com/cloudflare/cloudflared/releases` |

Запуск (в отдельном окне терминала, оно должно оставаться открытым):

```bash
cloudflared tunnel --url http://localhost:3006
```

Подставьте свой порт, если API слушает не 3006.

В выводе появится строка вида:

```
https://random-words-here.trycloudflare.com
```

Это и есть публичный адрес приложения.

### ngrok (альтернатива, нужен бесплатный аккаунт)

```bash
ngrok http 3006
```

Адрес вида `https://….ngrok-free.dev` в строке `Forwarding`.

## Что сделать с этим адресом

Записать его в настройки приложения как **базовый адрес** и строить от него ссылку,
которую получает кошелёк. В шаблоне `casco` это переменная окружения, из которой
собирается `redirect`:

```ts
const baseUrl = process.env.PUBLIC_BASE_URL; // https://….trycloudflare.com
const redirectUrl = new URL("/api/auth/login", baseUrl).toString();
const offer = `w3ds://auth?redirect=${redirectUrl}&session=${sessionId}&platform=<имя>`;
```

**Проверьте сами, до того как звать человека:**

```bash
curl -s -o /dev/null -w "%{http_code}\n" https://….trycloudflare.com/api/auth/offer
```

Должно быть `200`. Если `502` — туннель смотрит не на тот порт или приложение не запущено.

## Три вещи, на которых спотыкаются

**1. Адрес меняется при каждом перезапуске туннеля.** Бесплатный туннель Cloudflare выдаёт
новое случайное имя. Перезапустили — обновите переменную окружения и перезапустите API,
иначе кошелёк будет стучаться по старому адресу. Симптом: вчера работало, сегодня «ждём
подтверждения» навсегда.

**2. Фронтенд и API должны быть на одном публичном адресе.** Если фронтенд открыт
на `https://….trycloudflare.com`, а обращается к `http://localhost:3006` — браузер телефона
не достучится. Либо ведите туннель на порт, который отдаёт и фронтенд, и API, либо поднимите
два туннеля и пропишите адрес API явно.

**3. Туннель — только для разработки.** Как только приложение переезжает на настоящий
хостинг, базовым адресом становится его домен, а туннель выключается.

## Проверка, которая закрывает эти ворота

Человек берёт **телефон**, открывает публичный адрес в браузере телефона и видит страницу
приложения. Не описание страницы с ваших слов — саму страницу на своём экране.

Пока этого не произошло, переходить к входу по eID бессмысленно.
