login.go
1 package executor 2 3 import ( 4 "fmt" 5 "strings" 6 7 "codeflow.dananglin.me.uk/apollo/enbas/internal/config" 8 "codeflow.dananglin.me.uk/apollo/enbas/internal/gtsclient" 9 "codeflow.dananglin.me.uk/apollo/enbas/internal/model" 10 "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" 11 "codeflow.dananglin.me.uk/apollo/enbas/internal/server" 12 "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" 13 ) 14 15 func (l *LoginExecutor) Execute() error { 16 var err error 17 18 if l.instance == "" { 19 return Error{"please specify the instance that you want to log into"} 20 } 21 22 if !strings.HasPrefix(l.instance, "https") || !strings.HasPrefix(l.instance, "http") { 23 l.instance = "https://" + l.instance 24 } 25 26 for strings.HasSuffix(l.instance, "/") { 27 l.instance = l.instance[:len(l.instance)-1] 28 } 29 30 client, err := server.Connect(l.config.Server, l.configDir) 31 if err != nil { 32 return fmt.Errorf("error creating the client for the daemon process: %w", err) 33 } 34 defer client.Close() 35 36 // Update the GTSClient's auth details for the registration process. 37 auth := config.Credentials{ 38 Instance: l.instance, 39 ClientID: "", 40 ClientSecret: "", 41 AccessToken: "", 42 } 43 44 if err := client.Call("GTSClient.UpdateAuthentication", auth, nil); err != nil { 45 return fmt.Errorf("error updating the GTSClient's authentication details: %w", err) 46 } 47 48 if err := client.Call("GTSClient.Register", gtsclient.NoRPCArgs{}, nil); err != nil { 49 return fmt.Errorf("unable to register the application: %w", err) 50 } 51 52 var consentPageURL string 53 54 if err := client.Call("GTSClient.AuthCodeURL", gtsclient.NoRPCArgs{}, &consentPageURL); err != nil { 55 return fmt.Errorf("unable to get the URL of the consent page: %w", err) 56 } 57 58 _ = utilities.OpenLink(l.config.Integrations.Browser, consentPageURL) 59 60 var builder strings.Builder 61 62 builder.WriteString("\nYou'll need to sign into your GoToSocial's consent page in order to generate the out-of-band token to continue with the application's login process.") 63 builder.WriteString("\nYour browser may have opened the link to the consent page already. If not, please copy and paste the link below to your browser:") 64 builder.WriteString("\n\n" + consentPageURL) 65 builder.WriteString("\n\n" + "Once you have the code please copy and paste it below.") 66 builder.WriteString("\n" + "Out-of-band token: ") 67 68 printer.PrintInfo(builder.String()) 69 70 var code string 71 72 if _, err := fmt.Scanln(&code); err != nil { 73 return fmt.Errorf("failed to read access code: %w", err) 74 } 75 76 if err := client.Call("GTSClient.UpdateToken", code, &auth); err != nil { 77 return fmt.Errorf("unable to update the client's access token: %w", err) 78 } 79 80 var account model.Account 81 if err := client.Call("GTSClient.VerifyCredentials", gtsclient.NoRPCArgs{}, &account); err != nil { 82 return fmt.Errorf("unable to verify the credentials: %w", err) 83 } 84 85 loginName, err := config.SaveCredentials(l.config.CredentialsFile, account.Username, auth) 86 if err != nil { 87 return fmt.Errorf("unable to save the authentication details: %w", err) 88 } 89 90 printer.PrintSuccess(l.printSettings, "You have successfully logged in as "+loginName+".") 91 92 return nil 93 }