You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: deviceauth.go
    path of file: ./repos/encore/cli/internal/login
    
    the code of the file until where you have to start completion: package login

import (
	"context"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"os"
	"time"

	"github.com/briandowns/spinner"
	"github.com/fatih/color"

	"encr.dev/cli/cmd/encore/cmdutil"
	"encr.dev/cli/internal/browser"
	"encr.dev/cli/internal/platform"
	"encr.dev/internal/conf"
	"encr.dev/internal/env"
)

// DeviceAuth logs in the suser with the device auth flow.
func DeviceAuth() (*conf.Config, error) {
	// Generate PKCE challenge.
	randData, err := genRandData()
	if err != nil {
		return nil, fmt.Errorf("could not generate random data: %v", err)
	}
	codeVerifier := base64.RawURLEncoding.EncodeToString([]byte(randData))
	challengeHash := sha256.Sum256([]byte(codeVerifier))
	codeChallenge := base64.RawURLEncoding.EncodeToString(challengeHash[:])

	resp, err := platform.BeginDeviceAuthFlow(context.Background(), platform.BeginAuthorizationFlowParams{
		CodeChallenge: codeChallenge,
		ClientID:      "encore_cli",
	})
	if err != nil {
		return nil, err
	}

	var (
		bold  = color.New(color.Bold)
		faint = color.New(color.Faint)
	)

	fmt.Printf("Your pairing code is %s\n", bold.Sprint(resp.UserCode))
	faint.Println("This pairing code verifies your authentication with Encore.")

	inputCh := make(chan struct{}, 
    
func DeviceAuth() (*conf.Config, error) {
	// Generate PKCE challenge.
	randData, err := genRandData()
	if err != nil {
		return nil, fmt.Errorf("could not generate random data: %v", err)
	}
	codeVerifier := base64.RawURLEncoding.EncodeToString([]byte(randData))
	challengeHash := sha256.Sum256([]byte(codeVerifier))
	codeChallenge := base64.RawURLEncoding.EncodeToString(challengeHash[:])

	resp, err := platform.BeginDeviceAuthFlow(context.Background(), platform.BeginAuthorizationFlowParams{
		CodeChallenge: codeChallenge,
		ClientID:      "encore_cli",
	})
	if err != nil {
		return nil, err
	}

	var (
		bold  = color.New(color.Bold)
		faint = color.New(color.Faint)
	)

	fmt.Printf("Your pairing code is %s\n", bold.Sprint(resp.UserCode))
	faint.Println("This pairing code verifies your authentication with Encore.")

	inputCh := make(chan struct{}, 1)

	spin := spinner.New(spinner.CharSets[14], 100*time.Millisecond)
	spin.Prefix = "Waiting for login confirmation..."

	if !env.IsSSH() && browser.CanOpen() {
		fmt.Fprintf(os.Stdout, "Press Enter to open the browser or visit %s (^C to quit)\n",
			resp.VerificationURI)

		// Asynchronously wait for input.
		w := waitForEnterPress()
		defer w.Stop()
		go func() {
			select {
			case <-w.pressed:
				inputCh <- struct{}{}
			case <-w.quit:
			}
		}()

	} else {
		// On Windows we need a proper \r\n newline to ensure the URL detection doesn't extend to the next line.
		// fmt.Fprintln and family prints just a simple \n, so don't use that.
		fmt.Fprintf(os.Stdout, "To authenticate with Encore, please go to: %s%s", resp.VerificationURI, cmdutil.Newline)
		spin.Start()
	}

	resultCh := make(chan deviceAuthResult, 1)
	go pollForDeviceAuthResult(codeVerifier, resp, resultCh)

	for {
		select {
		case <-inputCh:
			// The user hit Enter; show a spinner and try to open the browser.
			spin.Start()
			if !browser.Open(resp.VerificationURI) {
				spin.FinalMSG = fmt.Sprintf("Failed to open browser, please go to %s manually.", resp.VerificationURI)
				spin.Stop()

				// Create a new spinner so the message above stays around.
				spin = spinner.New(spinner.CharSets[14], 100*time.Millisecond)
				spin.Prefix = "Waiting for login confirmation..."
				spin.Start()
			}

		case res := <-resultCh:
			if res.err != nil {
				spin.FinalMSG = fmt.Sprintf("Failed to log in: %v", res.err)
				spin.Stop()
				return nil, res.err
			}

			spin.Stop()
			return res.cfg, nil
		}
	}
}