feat(account): VK ID web login to link a VK identity from a browser
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 18s
CI / ui (pull_request) Successful in 1m4s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m39s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 18s
CI / ui (pull_request) Successful in 1m4s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m39s
A browser has no signed VK Mini App launch params, so linking VK on the web uses
VK ID's raw OAuth 2.1 flow (PKCE, no @vkid/sdk): the SPA redirects to VK's hosted
login and returns with an authorization code, which the gateway exchanges
server-side (confidential, under the VK "Web" app's protected key) for the trusted
vk user id — then the existing link/merge machinery attaches or merges it.
- fbs LinkVKRequest{code, device_id, code_verifier}; codec + TS bindings.
- backend link.Service ConfirmVK/MergeVK/attachVK (KindVK, mirror Telegram),
handleLinkVK[Merge], routes /user/link/vk[/merge], backendclient LinkVK[Merge].
- gateway internal/vkid confidential code exchange (id.vk.com/oauth2/auth);
transcode link.vk.confirm/merge (registered only when configured) + config
GATEWAY_VK_ID_{APP_ID,CLIENT_SECRET,REDIRECT_URL} + main wiring.
- UI lib/vkid (PKCE authorize redirect + callback), Profile "Link VK" control,
boot callback handling; a merge re-authorizes for a fresh code (VK codes are
single-use). Web-only (a redirect strands a Mini App webview).
- Deploy: VITE_VK_APP_ID + VITE_VK_ID_REDIRECT_URL build args + gateway env,
ci.yaml/prod-deploy TEST_/PROD_ vars, compose/Dockerfile/.env.example/README.
- Tests: vkid exchange unit (string/number user_id, id_token fallback, errors),
transcode link.vk, backend ConfirmVK/MergeVK inttest, codec encodeLinkVK.
- Docs: ARCHITECTURE §4, FUNCTIONAL(+ru), gateway README.
This commit is contained in:
+10
-2
@@ -257,11 +257,19 @@ arrive from a platform rather than completing a mandatory registration).
|
||||
control of the identity before attaching it: **email** through the confirm-code
|
||||
flow, **Telegram** through the web **Login Widget** (validated by the validator,
|
||||
HMAC under `SHA-256(bot_token)` — distinct from Mini App initData; the gateway
|
||||
passes the trusted `external_id` to the backend, as for `auth.telegram`). The
|
||||
passes the trusted `external_id` to the backend, as for `auth.telegram`), and **VK**
|
||||
through **VK ID web login** (`gateway/internal/vkid`): the browser runs the VK ID raw
|
||||
OAuth 2.1 flow with PKCE — a full-page redirect to VK's hosted login, no `@vkid/sdk` —
|
||||
and the gateway completes the **confidential code exchange** server-side under the VK
|
||||
"Web" app's protected key (a distinct VK app from the Mini App) to obtain the trusted
|
||||
`external_id`. A browser has no signed launch parameters, so unlike the VK Mini App
|
||||
(offline HMAC, §12) this makes an outbound call to `id.vk.com`, and it is web-only — a
|
||||
full-page redirect would strand a native Mini App webview. The
|
||||
request step **always** sends/accepts the proof (no pre-send "already taken"
|
||||
signal, so a probe cannot enumerate registered addresses); a required **merge**
|
||||
is revealed **only after** the proof is verified and is performed behind an
|
||||
explicit, irreversible confirmation. A free identity is simply attached (and a
|
||||
explicit, irreversible confirmation (for VK, whose authorization code is single-use,
|
||||
the merge re-authorizes for a fresh code). A free identity is simply attached (and a
|
||||
guest is promoted to durable, clearing `is_guest`).
|
||||
- **Unlink** detaches a platform identity (`telegram`/`vk`) from the profile. The
|
||||
backend **refuses removing the last identity** (`ErrLastIdentity`), so an account
|
||||
|
||||
+4
-2
@@ -108,8 +108,10 @@ account is kept and the guest's games move into it. A merge is blocked only whil
|
||||
two accounts share a game still in progress.
|
||||
|
||||
The profile lists the account's **sign-in methods**. On the web a player can add
|
||||
Telegram; adding VK on the web is not offered yet, and inside a Mini App the host
|
||||
platform is already linked. A linked provider can be **unlinked** — except the last
|
||||
Telegram (a login-widget popup) or VK (VK ID web login — a redirect to VK's sign-in and
|
||||
back); inside a Mini App the host platform is already linked. Linking a provider that
|
||||
already belongs to another account offers the same irreversible **merge** as email
|
||||
linking. A linked provider can be **unlinked** — except the last
|
||||
remaining sign-in method, which is refused so the account stays reachable. **Email is
|
||||
never unlinked; it is changed**: the player enters a new address, confirms a code
|
||||
mailed to it, and the account switches to it atomically, freeing the old address. A new
|
||||
|
||||
@@ -112,8 +112,10 @@ Telegram держит **единого бота**: все игроки поль
|
||||
запрещено, только пока у аккаунтов есть общая незавершённая игра.
|
||||
|
||||
В профиле перечислены **способы входа** аккаунта. В вебе игрок может добавить
|
||||
Telegram; добавление VK в вебе пока не предлагается, а внутри Mini App платформа-хозяин
|
||||
уже привязана. Привязанного провайдера можно **отвязать** — кроме последнего
|
||||
Telegram (попап логин-виджета) или VK (веб-вход VK ID — редирект на страницу входа VK и
|
||||
обратно); внутри Mini App платформа-хозяин уже привязана. Привязка провайдера, уже
|
||||
принадлежащего другому аккаунту, предлагает то же необратимое **слияние**, что и привязка
|
||||
email. Привязанного провайдера можно **отвязать** — кроме последнего
|
||||
оставшегося способа входа: он не отвязывается, чтобы аккаунт оставался достижимым.
|
||||
**Email не отвязывают — его меняют**: игрок вводит новый адрес, подтверждает код,
|
||||
отправленный на него, и аккаунт атомарно переключается на новый адрес, освобождая
|
||||
|
||||
Reference in New Issue
Block a user