feat(api): record account-link auth source (mojang|thirdparty)

Capture which Yggdrasil authenticated an in-game UUID when a link code is
minted (spec §10 dual-Yggdrasil) and copy it onto the durable account_links
row at verify. The value originates in-game — the web verify side never sees
the authentication — so it threads through account_link_codes, mirroring how
mc_uuid (not user_id) lives on a code.

- migration 0005: add link_auth_source enum + auth_source column on both
  account_link_codes and account_links; DEFAULT 'mojang' backfills existing
  rows and sets the Mojang-priority default for a mint that omits the field
- mint validates an explicit auth_source (unknown value -> 400); verify
  surfaces it in the 200 body and refreshes it on idempotent re-verify
This commit is contained in:
flyemoji committed 2026-06-27 13:01:19 +09:00
1 parent dbe34a175f
commit 1f8b9bb5d0
7 files changed
+179 -48

No files matched your search

+14 -1
View File
@@ -643,6 +643,15 @@ paths:
required: [mc_uuid]
properties:
mc_uuid: { type: string }
auth_source:
type: string
enum: [mojang, thirdparty]
default: mojang
description: >
Which Yggdrasil authenticated the in-game UUID (spec §10
dual-Yggdrasil). Optional; an omitted value defaults to the
Mojang-priority source. Captured here because only the in-game
side sees the authentication; it is copied onto the link at verify.
responses:
'201':
description: Code minted.
@@ -1427,10 +1436,14 @@ paths:
application/json:
schema:
type: object
required: [linked, mc_uuid]
required: [linked, mc_uuid, auth_source]
properties:
linked: { type: boolean, const: true }
mc_uuid: { type: string }
auth_source:
type: string
enum: [mojang, thirdparty]
description: The source captured at mint, copied onto the durable link.
'400':
description: Invalid or expired code.
content: