fix(setup): 绑定码可重试并说明连接方式
This commit is contained in:
12 files changed
+563
-51
No files matched your search
@@ -24,18 +24,18 @@ import (
|
||||
// ownership operation (claim, §9.3), which otherwise dead-ends at a 412.
|
||||
|
||||
const (
|
||||
// linkCodeTTL bounds how long a freshly minted code is accepted (spec §10:
|
||||
// LinkCodeTTL bounds how long a freshly minted code is accepted (spec §10:
|
||||
// 短 TTL). Long enough to alt-tab from the game to the panel, short enough that
|
||||
// a leaked code is useless minutes later.
|
||||
linkCodeTTL = 10 * time.Minute
|
||||
// linkCodeAlphabet is a 32-symbol set with the visually ambiguous characters
|
||||
LinkCodeTTL = 10 * time.Minute
|
||||
// LinkCodeAlphabet is a 32-symbol set with the visually ambiguous characters
|
||||
// I, O, 0 and 1 removed, so a player can read a code off chat and type it on the
|
||||
// panel without confusion. 32 divides 256 evenly, so a uniform random byte
|
||||
// reduced mod 32 is itself uniform — no modulo bias, no rejection sampling.
|
||||
linkCodeAlphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
||||
// linkCodeLen is the symbol count: a 32^8 ≈ 1.1e12 keyspace, far beyond brute
|
||||
LinkCodeAlphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
||||
// LinkCodeLen is the symbol count: a 32^8 ≈ 1.1e12 keyspace, far beyond brute
|
||||
// force inside the TTL.
|
||||
linkCodeLen = 8
|
||||
LinkCodeLen = 8
|
||||
|
||||
// authSource records which Yggdrasil established the in-game UUID when a code
|
||||
// was minted (spec §10, dual-Yggdrasil): the official Mojang service, or a
|
||||
@@ -97,12 +97,12 @@ func deriveAuthSource(mcUUID string) string {
|
||||
|
||||
// newLinkCode returns a cryptographically random, unambiguous link code.
|
||||
func newLinkCode() (string, error) {
|
||||
buf := make([]byte, linkCodeLen)
|
||||
buf := make([]byte, LinkCodeLen)
|
||||
if _, err := rand.Read(buf); err != nil {
|
||||
return "", err
|
||||
}
|
||||
for i, b := range buf {
|
||||
buf[i] = linkCodeAlphabet[int(b)%len(linkCodeAlphabet)]
|
||||
buf[i] = LinkCodeAlphabet[int(b)%len(LinkCodeAlphabet)]
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func (a *API) handleCreateLinkCode(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, r, err)
|
||||
return
|
||||
}
|
||||
expiresAt := a.now().Add(linkCodeTTL)
|
||||
expiresAt := a.now().Add(LinkCodeTTL)
|
||||
if err := a.Repo.CreateLinkCode(r.Context(), code, mcUUID, authSource, expiresAt); err != nil {
|
||||
writeError(w, r, err)
|
||||
return
|
||||
|
||||
@@ -50,8 +50,8 @@ func TestAccountLinkVertical(t *testing.T) {
|
||||
t.Fatalf("mint code: code = %d, want 201 (%s)", w.Code, w.Body.String())
|
||||
}
|
||||
code, _ := acctBody(t, w)["code"].(string)
|
||||
if len(code) != linkCodeLen {
|
||||
t.Fatalf("minted code %q: len = %d, want %d", code, len(code), linkCodeLen)
|
||||
if len(code) != LinkCodeLen {
|
||||
t.Fatalf("minted code %q: len = %d, want %d", code, len(code), LinkCodeLen)
|
||||
}
|
||||
|
||||
// 2) the player submits the code on the panel (external face).
|
||||
@@ -113,11 +113,11 @@ func TestCreateLinkCode(t *testing.T) {
|
||||
if rec.authSource != authSourceMojang {
|
||||
t.Errorf("default authSource = %q, want %q", rec.authSource, authSourceMojang)
|
||||
}
|
||||
if want := api.now().Add(linkCodeTTL); !rec.expiresAt.Equal(want) {
|
||||
if want := api.now().Add(LinkCodeTTL); !rec.expiresAt.Equal(want) {
|
||||
t.Errorf("expiresAt = %v, want %v", rec.expiresAt, want)
|
||||
}
|
||||
for _, c := range code {
|
||||
if !strings.ContainsRune(linkCodeAlphabet, c) {
|
||||
if !strings.ContainsRune(LinkCodeAlphabet, c) {
|
||||
t.Errorf("code %q contains out-of-alphabet rune %q", code, c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func seedBindAPI(t *testing.T) (*API, *fakeRepo) {
|
||||
// mint (handleCreateLinkCode → CreateLinkCode).
|
||||
func mintBindCode(t *testing.T, api *API, repo *fakeRepo, code, uuid, authSource string) {
|
||||
t.Helper()
|
||||
if err := repo.CreateLinkCode(t.Context(), code, uuid, authSource, api.now().Add(linkCodeTTL)); err != nil {
|
||||
if err := repo.CreateLinkCode(t.Context(), code, uuid, authSource, api.now().Add(LinkCodeTTL)); err != nil {
|
||||
t.Fatalf("mint bind code: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user