From 4db7a72ecb425e69e709639f4069978ead1f79fa Mon Sep 17 00:00:00 2001 From: zhaojunchang Date: Tue, 31 Mar 2026 23:33:43 +0800 Subject: [PATCH 1/4] fix: Fix the issue where the URL returned by the "lark-cli auth login --no-wait" command contains \u0026 --- cmd/auth/login.go | 16 ++++++++++------ cmd/root.go | 11 +++++++++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 572965d3b..b827779ea 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -225,26 +225,30 @@ func authLoginRun(opts *LoginOptions) error { // --no-wait: return immediately with device code and URL if opts.NoWait { - b, _ := json.Marshal(map[string]interface{}{ + data := map[string]interface{}{ "verification_url": authResp.VerificationUriComplete, "device_code": authResp.DeviceCode, "expires_in": authResp.ExpiresIn, "hint": fmt.Sprintf("Show verification_url to user, then immediately execute: lark-cli auth login --device-code %s (blocks until authorized or timeout). Do not instruct the user to run this command themselves.", authResp.DeviceCode), - }) - fmt.Fprintln(f.IOStreams.Out, string(b)) + } + encoder := json.NewEncoder(f.IOStreams.Out) + encoder.SetEscapeHTML(false) + encoder.Encode(data) return nil } // Step 2: Show user code and verification URL if opts.JSON { - b, _ := json.Marshal(map[string]interface{}{ + data := map[string]interface{}{ "event": "device_authorization", "verification_uri": authResp.VerificationUri, "verification_uri_complete": authResp.VerificationUriComplete, "user_code": authResp.UserCode, "expires_in": authResp.ExpiresIn, - }) - fmt.Fprintln(f.IOStreams.Out, string(b)) + } + encoder := json.NewEncoder(f.IOStreams.Out) + encoder.SetEscapeHTML(false) + encoder.Encode(data) } else { fmt.Fprintf(f.IOStreams.ErrOut, msg.OpenURL) fmt.Fprintf(f.IOStreams.ErrOut, " %s\n\n", authResp.VerificationUriComplete) diff --git a/cmd/root.go b/cmd/root.go index 4a6daf9f6..15b50cab1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,6 +4,7 @@ package cmd import ( + "bytes" "encoding/json" "errors" "fmt" @@ -241,12 +242,18 @@ func writeSecurityPolicyError(w io.Writer, spErr *internalauth.SecurityPolicyErr } env := map[string]interface{}{"ok": false, "error": errData} - b, err := json.MarshalIndent(env, "", " ") + + buffer := &bytes.Buffer{} + encoder := json.NewEncoder(buffer) + encoder.SetEscapeHTML(false) + encoder.SetIndent("", " ") + err := encoder.Encode(env) + if err != nil { fmt.Fprintln(w, `{"ok":false,"error":{"type":"internal_error","code":"marshal_error","message":"failed to marshal error"}}`) return } - fmt.Fprintln(w, string(b)) + fmt.Fprint(w, buffer.String()) } // installTipsHelpFunc wraps the default help function to append a TIPS section From b7aa40bca6a4a529e989dd40866a32e267b4dc3c Mon Sep 17 00:00:00 2001 From: zhaojunchang Date: Wed, 1 Apr 2026 11:51:13 +0800 Subject: [PATCH 2/4] style: fix indentation and whitespace in error handling code --- cmd/root.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 15b50cab1..6168dbdeb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -242,13 +242,13 @@ func writeSecurityPolicyError(w io.Writer, spErr *internalauth.SecurityPolicyErr } env := map[string]interface{}{"ok": false, "error": errData} - + buffer := &bytes.Buffer{} encoder := json.NewEncoder(buffer) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") err := encoder.Encode(env) - + if err != nil { fmt.Fprintln(w, `{"ok":false,"error":{"type":"internal_error","code":"marshal_error","message":"failed to marshal error"}}`) return From b2b05725a188fcd3b32ebc4cc46e447a9e192e66 Mon Sep 17 00:00:00 2001 From: zhaojunchang Date: Wed, 1 Apr 2026 13:02:52 +0800 Subject: [PATCH 3/4] fix(auth): handle JSON encoding errors in login output --- cmd/auth/login.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index b827779ea..00dae7e4c 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -233,7 +233,9 @@ func authLoginRun(opts *LoginOptions) error { } encoder := json.NewEncoder(f.IOStreams.Out) encoder.SetEscapeHTML(false) - encoder.Encode(data) + if err := encoder.Encode(data); err != nil { + fmt.Fprintf(f.IOStreams.ErrOut, "error: failed to write JSON output: %v\n", err) + } return nil } @@ -248,7 +250,9 @@ func authLoginRun(opts *LoginOptions) error { } encoder := json.NewEncoder(f.IOStreams.Out) encoder.SetEscapeHTML(false) - encoder.Encode(data) + if err := encoder.Encode(data); err != nil { + fmt.Fprintf(f.IOStreams.ErrOut, "error: failed to write JSON output: %v\n", err) + } } else { fmt.Fprintf(f.IOStreams.ErrOut, msg.OpenURL) fmt.Fprintf(f.IOStreams.ErrOut, " %s\n\n", authResp.VerificationUriComplete) From 0ddf1a52dcc7cd91958ccaf934aec4c83ac455cf Mon Sep 17 00:00:00 2001 From: zhaojunchang Date: Wed, 1 Apr 2026 13:16:09 +0800 Subject: [PATCH 4/4] docs(cmd/auth): add comment for authLoginRun function --- cmd/auth/login.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 00dae7e4c..ebd744f28 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -90,6 +90,7 @@ func completeDomain(toComplete string) []string { return completions } +// authLoginRun executes the login command logic. func authLoginRun(opts *LoginOptions) error { f := opts.Factory