diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 572965d3b..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 @@ -225,26 +226,34 @@ 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) + if err := encoder.Encode(data); err != nil { + fmt.Fprintf(f.IOStreams.ErrOut, "error: failed to write JSON output: %v\n", err) + } 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) + 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) diff --git a/cmd/root.go b/cmd/root.go index 4a6daf9f6..6168dbdeb 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