diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index c326ad2..223bc07 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -244,8 +244,9 @@ arrive from a platform rather than completing a mandatory registration). 256-bit token stored only as its SHA-256, 12-hour TTL): a login mints a session in the browser that opens it (magic-link), a link confirms the identity and emits a `notify` profile-refresh to the in-app session, and a would-be merge is deferred to the - interactive flow. The confirm page is prefetch-safe — it confirms only on a button - press, so a mail scanner's GET does not consume the single-use token. An + interactive flow. The confirm runs on load; the token rides the URL fragment (never + sent to the server), so a plain link prefetch cannot reach it, and the manual + six-digit code is the fallback if an aggressive scanner runs the page. An **email-login** account is created flagged `is_guest` and stays reapable until the code is confirmed — so an abandoned, never-confirmed login frees its reserved address — with confirming clearing the flag. Accounts and identities use diff --git a/docs/FUNCTIONAL.md b/docs/FUNCTIONAL.md index abafd3c..ec82aef 100644 --- a/docs/FUNCTIONAL.md +++ b/docs/FUNCTIONAL.md @@ -69,7 +69,8 @@ freed. Sends are rate-limited (a short cooldown between codes and a small hourly per address), so a mistyped address or an impatient tap cannot flood an inbox. The email also carries a **one-tap link** that confirms the address — or signs the player straight in — in a single tap; opening it in another browser reflects in the app at once, and a -mail scanner that merely fetches the link never triggers it (it acts only on a button press). +mail scanner that merely fetches the link cannot reach it — the token rides the URL +fragment, which is never sent to the server. Telegram runs a **single bot**: every player uses the same bot, and all of its chat and out-of-app notifications are written in the player's own **interface language** (en/ru). A separate optional **promo bot** can run alongside the diff --git a/docs/FUNCTIONAL_ru.md b/docs/FUNCTIONAL_ru.md index 690ddfb..410a46a 100644 --- a/docs/FUNCTIONAL_ru.md +++ b/docs/FUNCTIONAL_ru.md @@ -73,8 +73,8 @@ launch-параметрам VK (их проверяет gateway), и при пе пауза между кодами и небольшой часовой лимит на адрес), чтобы опечатка в адресе или нетерпеливый тап не завалили почтовый ящик. В письме также есть **ссылка одного нажатия**, которая подтверждает адрес — или сразу выполняет вход — в один тап; открытие её в другом браузере тут же отражается в -приложении, а почтовый сканер, который просто загружает ссылку, её не срабатывает (действие -только по нажатию кнопки). +приложении, а почтовый сканер, который просто загружает ссылку, до токена не дотянется — +он едет в URL-фрагменте, который не уходит на сервер. Telegram держит **единого бота**: все игроки пользуются одним и тем же ботом, а весь его чат и внеприложенческие уведомления пишутся на **языке интерфейса** самого игрока (en/ru). Рядом с основным может работать отдельный опциональный diff --git a/ui/src/lib/i18n/en.ts b/ui/src/lib/i18n/en.ts index 10f4634..6a7cce1 100644 --- a/ui/src/lib/i18n/en.ts +++ b/ui/src/lib/i18n/en.ts @@ -36,8 +36,7 @@ export const en = { 'login.sendCode': 'Send code', 'login.codePlaceholder': '6-digit code', 'login.signIn': 'Sign in', - 'confirm.prompt': 'Confirm your email to finish.', - 'confirm.action': 'Confirm', + 'confirm.busy': 'Confirming your email…', 'confirm.linked': 'Email confirmed.', 'confirm.merge': 'Almost done — finish the merge in the app.', 'confirm.close': 'You can close this window and return to the game.', diff --git a/ui/src/lib/i18n/ru.ts b/ui/src/lib/i18n/ru.ts index 9cd928c..063b652 100644 --- a/ui/src/lib/i18n/ru.ts +++ b/ui/src/lib/i18n/ru.ts @@ -37,8 +37,7 @@ export const ru: Record = { 'login.sendCode': 'Отправить код', 'login.codePlaceholder': 'Код из 6 цифр', 'login.signIn': 'Войти', - 'confirm.prompt': 'Подтвердите почту, чтобы завершить.', - 'confirm.action': 'Подтвердить', + 'confirm.busy': 'Подтверждаем почту…', 'confirm.linked': 'Почта подтверждена.', 'confirm.merge': 'Почти готово — завершите объединение в приложении.', 'confirm.close': 'Можно закрыть это окно и вернуться в игру.', diff --git a/ui/src/screens/Confirm.svelte b/ui/src/screens/Confirm.svelte index 5af9f62..d97b31a 100644 --- a/ui/src/screens/Confirm.svelte +++ b/ui/src/screens/Confirm.svelte @@ -1,37 +1,35 @@
{t('app.title')}
- {#if stage === 'idle' || stage === 'busy'} -

{t('confirm.prompt')}

- + {#if stage === 'busy'} +

{t('confirm.busy')}

{:else if stage === 'linked'}

{t('confirm.linked')}

{t('confirm.close')}

@@ -81,15 +79,4 @@ .err { color: var(--danger, #c0392b); } - button { - padding: 12px; - border-radius: var(--radius-sm); - border: 1px solid var(--accent); - font-weight: 600; - background: var(--accent); - color: var(--accent-text); - } - button:disabled { - opacity: 0.5; - }