1414package main
1515
1616import (
17+ "bytes"
1718 "context"
1819 "flag"
1920 "fmt"
@@ -31,6 +32,7 @@ import (
3132
3233 "golang.org/x/oauth2"
3334 "golang.org/x/oauth2/endpoints"
35+ "rsc.io/qr"
3436)
3537
3638// configByHost lists default config for several public hosts.
@@ -499,10 +501,47 @@ func getDeviceToken(ctx context.Context, c oauth2.Config) (*oauth2.Token, error)
499501 if verbose {
500502 fmt .Fprintf (os .Stderr , "%+v\n " , deviceAuth )
501503 }
502- fmt .Fprintf (os .Stderr , "Please enter code %s at %s\n " , deviceAuth .UserCode , deviceAuth .VerificationURI )
504+ if deviceAuth .VerificationURIComplete != "" {
505+ fmt .Fprintf (os .Stderr , "Please scan the QR code or enter code %s at %s\n " , deviceAuth .UserCode , deviceAuth .VerificationURI )
506+ writeQRCode (os .Stderr , deviceAuth .VerificationURIComplete )
507+ } else {
508+ fmt .Fprintf (os .Stderr , "Please enter code %s at %s\n " , deviceAuth .UserCode , deviceAuth .VerificationURI )
509+ }
503510 return c .DeviceAccessToken (ctx , deviceAuth )
504511}
505512
513+ func writeQRCode (w io.Writer , data string ) error {
514+ // use low redundancy to generate small QR codes for terminal output.
515+ // we assume the user is sitting in front of their screen so image quality shouldn't be an issue
516+ code , err := qr .Encode (data , qr .L )
517+ if err != nil {
518+ return err
519+ }
520+
521+ var (
522+ black = "\033 [40m \033 [0m"
523+ white = "\033 [107m \033 [0m"
524+ whiteLine = strings .Repeat (white , code .Size + 2 ) + "\n "
525+ buf bytes.Buffer
526+ )
527+ buf .WriteString (whiteLine )
528+ for y := range code .Size {
529+ for x := range code .Size {
530+ if code .Black (x , y ) {
531+ buf .WriteString (black )
532+ } else {
533+ buf .WriteString (white )
534+ }
535+ }
536+ buf .WriteString (white )
537+ buf .WriteRune ('\n' )
538+ }
539+ buf .WriteString (whiteLine )
540+
541+ _ , err = buf .WriteTo (w )
542+ return err
543+ }
544+
506545func replaceHost (e oauth2.Endpoint , host string ) oauth2.Endpoint {
507546 e .AuthURL = replaceHostInURL (e .AuthURL , host )
508547 e .TokenURL = replaceHostInURL (e .TokenURL , host )
0 commit comments