fix: keep failed login authentication unchanged

This commit is contained in:
2026-07-22 16:09:01 +08:00
parent 12ba947f9b
commit a174a22bcb
3 changed files with 95 additions and 39 deletions
+54
View File
@@ -8,6 +8,7 @@ import (
"net/http/httptest"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
)
@@ -115,6 +116,12 @@ func TestFreshMemoryClientQRLoginPersistsThroughCallback(t *testing.T) {
server = httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
switch request.URL.Path {
case "/serviceLogin":
deviceID, deviceErr := request.Cookie("deviceId")
passO, passOErr := request.Cookie("pass_o")
if request.UserAgent() == "" || deviceErr != nil || deviceID.Value == "" || passOErr != nil || passO.Value == "" {
http.Error(writer, "missing generated login identity", http.StatusBadRequest)
return
}
_, _ = io.WriteString(writer, `&&&START&&&{"code":70016,"location":"`+server.URL+`/prepare"}`)
case "/loginUrl":
_, _ = io.WriteString(writer, `&&&START&&&{"code":0,"loginUrl":"https://qr.example/login","lp":"`+server.URL+`/lp"}`)
@@ -148,6 +155,53 @@ func TestFreshMemoryClientQRLoginPersistsThroughCallback(t *testing.T) {
}
}
func TestFreshMemoryClientQRLoginCallbackFailureKeepsZeroAuthData(t *testing.T) {
var client *Client
var callbackCalls int
var server *httptest.Server
server = httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
switch request.URL.Path {
case "/serviceLogin":
_, _ = io.WriteString(writer, `&&&START&&&{"code":70016,"location":"`+server.URL+`/prepare"}`)
case "/loginUrl":
_, _ = io.WriteString(writer, `&&&START&&&{"code":0,"loginUrl":"https://qr.example/login","lp":"`+server.URL+`/lp"}`)
case "/lp":
_, _ = io.WriteString(writer, `&&&START&&&{"code":0,"ssecurity":"`+testSsecurity+`","passToken":"pass","userId":"user","cUserId":"c-user","location":"`+server.URL+`/callback"}`)
case "/callback":
http.SetCookie(writer, &http.Cookie{Name: "serviceToken", Value: "service", Path: "/"})
_, _ = io.WriteString(writer, "ok")
default:
http.NotFound(writer, request)
}
}))
defer server.Close()
var err error
client, err = NewClientWithAuthData(AuthData{}, WithHTTPClient(server.Client()), WithQRWriter(io.Discard), WithAuthDataChanged(func(AuthData) error {
callbackCalls++
if current := client.AuthData(); !reflect.DeepEqual(current, AuthData{}) {
t.Fatalf("auth data installed before callback completed: %#v", current)
}
return errAuthDataChanged
}))
if err != nil {
t.Fatal(err)
}
client.serviceLoginURL = server.URL + "/serviceLogin"
client.loginURL = server.URL + "/loginUrl"
_, err = client.Login(context.Background())
if !errors.Is(err, errAuthDataChanged) {
t.Fatalf("Login() error = %v, want %v", err, errAuthDataChanged)
}
if callbackCalls != 1 {
t.Fatalf("auth data changed callback calls = %d, want 1", callbackCalls)
}
if authData := client.AuthData(); !reflect.DeepEqual(authData, AuthData{}) {
t.Fatalf("auth data after callback failure = %#v, want exact zero value", authData)
}
}
func TestFileRefreshPersistenceFailureRollsBack(t *testing.T) {
directory := t.TempDir()
authPath := filepath.Join(directory, "auth.json")