This commit introduces several improvements to the ESI (EVE Server Interface) Single Sign-On (SSO) flow and system name resolution: **ESI SSO Login Flow:** - **Asynchronous Callback Server:** The `StartCallbackServer` function is now deprecated in favor of `StartCallbackServerAsync`. This allows the callback server to run in the background without blocking the main application thread, improving responsiveness. - **Improved Login Status Polling:** After initiating the ESI login, the frontend now polls the `ESILoggedIn` status for a short period. This ensures that the UI reflects the login status more accurately and promptly after the user completes the authentication flow in their browser. - **Error Handling:** Added more specific error messages for failed token exchanges and invalid SSO responses. **System Name Resolution:** - **Multi-stage Resolution:** The `ResolveSystemIDByName` function now employs a more robust, multi-stage approach to find system IDs: 1. It first attempts to use the `universe/ids` endpoint for direct name-to-ID mapping, which is generally more accurate. 2. If that fails, it falls back to a `strict` search via the `search` endpoint. 3. As a final fallback, it performs a non-strict search and then resolves the names of the returned IDs to find an exact case-insensitive match. If no exact match is found, it returns the first result. - **Logging:** Added more detailed logging for each stage of the system name resolution process, aiding in debugging. - **ESI API Headers:** Ensured that necessary headers like `Accept` and `X-User-Agent` are correctly set for ESI API requests. **Frontend Changes:** - **Import `ESILoggedIn`:** The `ESILoggedIn` function is now imported into the `Header.tsx` component. - **Updated Toast Message:** The toast message for setting a destination now includes the system name for better context in case of errors.
100 lines
2.4 KiB
Go
100 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
|
)
|
|
|
|
// App struct
|
|
type App struct {
|
|
ctx context.Context
|
|
ssi *ESISSO
|
|
}
|
|
|
|
// NewApp creates a new App application struct
|
|
func NewApp() *App {
|
|
return &App{}
|
|
}
|
|
|
|
// startup is called when the app starts. The context is saved
|
|
// so we can call the runtime methods
|
|
func (a *App) startup(ctx context.Context) {
|
|
a.ctx = ctx
|
|
|
|
clientID := os.Getenv("EVE_SSO_CLIENT_ID")
|
|
if clientID == "" {
|
|
clientID = "5091f74037374697938384bdbac2698c"
|
|
}
|
|
redirectURI := os.Getenv("EVE_SSO_REDIRECT_URI")
|
|
if redirectURI == "" {
|
|
redirectURI = "http://localhost:8080/callback"
|
|
}
|
|
|
|
a.ssi = NewESISSO(clientID, redirectURI, []string{"esi-ui.write_waypoint.v1"})
|
|
}
|
|
|
|
// Greet returns a greeting for the given name
|
|
func (a *App) Greet(name string) string {
|
|
return fmt.Sprintf("Hello %s, It's show time!", name)
|
|
}
|
|
|
|
// StartESILogin begins the PKCE SSO flow and opens a browser to the EVE login page
|
|
func (a *App) StartESILogin() (string, error) {
|
|
if a.ssi == nil {
|
|
return "", errors.New("ESI not initialised")
|
|
}
|
|
url, err := a.ssi.BuildAuthorizeURL()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if err := a.ssi.StartCallbackServerAsync(); err != nil {
|
|
return "", err
|
|
}
|
|
runtime.BrowserOpenURL(a.ctx, url)
|
|
return url, nil
|
|
}
|
|
|
|
// ESILoginStatus returns a short status string of the active token/character
|
|
func (a *App) ESILoginStatus() string {
|
|
if a.ssi == nil {
|
|
return "not initialised"
|
|
}
|
|
st := a.ssi.Status()
|
|
if st.LoggedIn {
|
|
return fmt.Sprintf("logged in as %s (%d)", st.CharacterName, st.CharacterID)
|
|
}
|
|
return "not logged in"
|
|
}
|
|
|
|
// ESILoggedIn returns true if a valid access token is present
|
|
func (a *App) ESILoggedIn() bool {
|
|
if a.ssi == nil {
|
|
return false
|
|
}
|
|
return a.ssi.Status().LoggedIn
|
|
}
|
|
|
|
// SetDestination posts a waypoint to ESI to set destination
|
|
func (a *App) SetDestination(destinationID int64, clearOthers bool, addToBeginning bool) error {
|
|
if a.ssi == nil {
|
|
return errors.New("ESI not initialised")
|
|
}
|
|
return a.ssi.PostWaypoint(destinationID, clearOthers, addToBeginning)
|
|
}
|
|
|
|
// SetDestinationByName resolves a solar system name to ID and sets destination
|
|
func (a *App) SetDestinationByName(systemName string, clearOthers bool, addToBeginning bool) error {
|
|
if a.ssi == nil {
|
|
return errors.New("ESI not initialised")
|
|
}
|
|
id, err := a.ssi.ResolveSystemIDByName(a.ctx, systemName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return a.ssi.PostWaypoint(id, clearOthers, addToBeginning)
|
|
}
|