fix(login)!: switch UI to token-only auth (#693)

This commit is contained in:
Ayyan 2026-01-09 23:35:59 -05:00 • committed by GitHub
parent 28857a9fb7
commit ba4718a168
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 9 additions and 100 deletions

View file

@ -48,13 +48,13 @@ go build .
## Usage
### Password
### Token (UI)
1. Run the `discordo` executable with no arguments.
2. Enter your email and password and click on the "Login" button to continue.
2. Enter your token and click on the "Login" button to save it.
### Token
### Token (CLI)
Provide the `token` command-line flag to the executable.
@ -64,9 +64,6 @@ discordo --token "OTI2MDU5NTQxNDE2Nzc5ODA2.Yc2KKA.2iZ-5JxgxG-9Ub8GHzBSn-NJjNg"
Alternatively, set the value of the `DISCORDO_TOKEN` environment variable to the authentication token.
> [!TIP]
> You can manually set the token to the keyring using the instructions [here](#manually-adding-token-to-keyring).
### QR
1. Run the `discordo` executable with no arguments.
@ -85,48 +82,5 @@ The configuration file allows you to configure and customize the behavior, keybi
Discordo uses the default configuration if a configuration file is not found in the aforementioned path; however, the default configuration file is not written to the path. [The default configuration can be found here](./internal/config/config.toml).
## FAQ
### Manually adding token to keyring
Do this if you get the error:
> failed to get token from keyring: secret not found in keyring
#### Windows
Run the following command in a terminal window. Replace `YOUR_DISCORD_TOKEN` with your authentication token.
```sh
cmdkey /add:discordo /user:token /pass:YOUR_DISCORD_TOKEN
```
#### MacOS
Run the following command in a terminal window. Replace `YOUR_DISCORD_TOKEN` with your authentication token.
```sh
security add-generic-password -s discordo -a token -w "YOUR_DISCORD_TOKEN"
```
#### Linux
1. Start the keyring daemon.
```sh
eval $(gnome-keyring-daemon --start)
export $(gnome-keyring-daemon --start)
```
2. Create the `login` keyring if it does not exist already. See [GNOME/Keyring](https://wiki.archlinux.org/title/GNOME/Keyring) for more information.
3. Run the following command to create the `token` entry.
```sh
secret-tool store --label="Discord Token" service discordo username token
```
4. When it prompts for the password, paste your token, and hit enter to confirm.
> [!IMPORTANT]
> Automated user accounts or "self-bots" are against Discord's Terms of Service. I am not responsible for any loss caused by using "self-bots" or Discordo.

View file

@ -5,11 +5,9 @@ import (
"log/slog"
"github.com/ayn2op/discordo/internal/config"
"github.com/ayn2op/discordo/internal/http"
"github.com/ayn2op/discordo/internal/keyring"
"github.com/ayn2op/discordo/internal/ui"
"github.com/ayn2op/tview"
"github.com/diamondburned/arikawa/v3/api"
"golang.design/x/clipboard"
)
@ -39,9 +37,7 @@ func NewForm(app *tview.Application, cfg *config.Config, done DoneFn) *Form {
}
f.form.
AddInputField("Email", "", 0, nil).
AddPasswordField("Password", "", 0, 0, nil).
AddPasswordField("Code (optional)", "", 0, 0, nil).
AddPasswordField("Token", "", 0, 0, nil).
AddButton("Login", f.login).
AddButton("Login with QR", f.loginWithQR)
f.AddAndSwitchToPage(formPageName, f.form, true)
@ -49,57 +45,16 @@ func NewForm(app *tview.Application, cfg *config.Config, done DoneFn) *Form {
}
func (f *Form) login() {
email := f.form.GetFormItem(0).(*tview.InputField).GetText()
password := f.form.GetFormItem(1).(*tview.InputField).GetText()
if email == "" || password == "" {
token := f.form.GetFormItem(0).(*tview.InputField).GetText()
if token == "" {
f.onError(errors.New("token required"))
return
}
// Create an API client without an authentication token.
client := api.NewClient("")
props := http.IdentifyProperties()
if browserUserAgent, ok := props["browser_user_agent"]; ok {
if val, ok := browserUserAgent.(string); ok {
api.UserAgent = val
}
}
resp, err := client.Login(email, password)
if err != nil {
f.onError(err)
return
}
if resp.MFA {
switch {
case resp.TOTP:
code := f.form.GetFormItem(2).(*tview.InputField).GetText()
if code == "" {
f.onError(errors.New("code required"))
return
}
// Attempt to login using the code.
resp, err = client.TOTP(code, resp.Ticket)
if err != nil {
f.onError(err)
return
}
default:
f.onError(errors.New("unsupported mfa type"))
return
}
}
if resp.Token == "" {
f.onError(errors.New("missing token"))
return
}
go keyring.SetToken(resp.Token)
go keyring.SetToken(token)
if f.done != nil {
f.done(resp.Token)
f.done(token)
}
}