fix(login)!: switch UI to token-only auth (#693)
This commit is contained in:
parent
28857a9fb7
commit
ba4718a168
2 changed files with 9 additions and 100 deletions
52
README.md
52
README.md
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue