diff options
| author | pg9182 <96569817+pg9182@users.noreply.github.com> | 2022-10-14 13:23:19 -0400 |
|---|---|---|
| committer | pg9182 <96569817+pg9182@users.noreply.github.com> | 2022-10-14 13:23:19 -0400 |
| commit | 01155bde059e93700ea4b8bd47e6835b8232f57c (patch) | |
| tree | 2d7c337aeb9e99a238986ab84300399fe36fdbb6 | |
| parent | 04096e175a60ffaf247a03f5cb9d94909e7409c2 (diff) | |
| download | Atlas-01155bde059e93700ea4b8bd47e6835b8232f57c.tar.gz Atlas-01155bde059e93700ea4b8bd47e6835b8232f57c.zip | |
pkg/origin, cmd/origin-login-test: Return nucleus token expiry
| -rw-r--r-- | cmd/origin-login-test/main.go | 6 | ||||
| -rw-r--r-- | pkg/origin/login.go | 34 |
2 files changed, 26 insertions, 14 deletions
diff --git a/cmd/origin-login-test/main.go b/cmd/origin-login-test/main.go index f543e62..cd259a3 100644 --- a/cmd/origin-login-test/main.go +++ b/cmd/origin-login-test/main.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "os" + "time" "github.com/cardigann/harhar" "github.com/pg9182/atlas/pkg/origin" @@ -76,12 +77,15 @@ func main() { } if !fail { - token, err := origin.GetNucleusToken(ctx, sid) + token, expiry, err := origin.GetNucleusToken(ctx, sid) if err != nil { fmt.Fprintf(os.Stderr, "origin: error: %v\n", err) fail = true } else { fmt.Printf("NucleusToken=%s\n", token) + fmt.Printf("NucleusTokenExpiry=%d\n", expiry.Unix()) + fmt.Printf("NucleusTokenExpirySecs=%.0f\n", time.Until(expiry).Seconds()) + fmt.Printf("NucleusTokenExpiryDuration=%s\n", time.Until(expiry).Truncate(time.Second)) } } diff --git a/pkg/origin/login.go b/pkg/origin/login.go index db40072..2eae807 100644 --- a/pkg/origin/login.go +++ b/pkg/origin/login.go @@ -14,6 +14,7 @@ import ( "net/url" "regexp" "strings" + "time" "github.com/andybalholm/cascadia" "golang.org/x/net/html" @@ -400,11 +401,11 @@ func login3(_ context.Context, c *http.Client, r2 *http.Request) (string, error) return code, nil } -// GetNucleusToken generates a Nucleus SID/AuthToken from the active session. -// Note that this token generally lasts ~4h. +// GetNucleusToken generates a Nucleus AuthToken from the active session. Note +// that this token generally lasts ~4h. // // If errors.Is(err, ErrAuthRequired), you need a new SID. -func GetNucleusToken(ctx context.Context, sid SID) (NucleusToken, error) { +func GetNucleusToken(ctx context.Context, sid SID) (NucleusToken, time.Time, error) { jar, _ := cookiejar.New(nil) c := &http.Client{ @@ -424,7 +425,7 @@ func GetNucleusToken(ctx context.Context, sid SID) (NucleusToken, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://accounts.ea.com/connect/auth?client_id=ORIGIN_JS_SDK&response_type=token&redirect_uri=nucleus:rest&prompt=none&release_type=prod", nil) if err != nil { - return "", err + return "", time.Time{}, err } req.Header.Set("Referrer", "https://www.origin.com/") @@ -432,13 +433,13 @@ func GetNucleusToken(ctx context.Context, sid SID) (NucleusToken, error) { resp, err := c.Do(req) if err != nil { - return "", fmt.Errorf("get nucleus token: %w", err) + return "", time.Time{}, fmt.Errorf("get nucleus token: %w", err) } defer resp.Body.Close() buf, err := io.ReadAll(resp.Body) if err != nil { - return "", fmt.Errorf("get nucleus token: %w", err) + return "", time.Time{}, fmt.Errorf("get nucleus token: %w", err) } if resp.StatusCode != http.StatusOK { @@ -448,12 +449,12 @@ func GetNucleusToken(ctx context.Context, sid SID) (NucleusToken, error) { ErrorNumber json.Number `json:"error_number"` } if obj.ErrorCode == "login_required" { - return "", fmt.Errorf("get nucleus token: %w: login required", ErrAuthRequired) + return "", time.Time{}, fmt.Errorf("get nucleus token: %w: login required", ErrAuthRequired) } if err := json.Unmarshal(buf, &obj); err == nil && obj.Error != "" { - return "", fmt.Errorf("get nucleus token: %w: error %s: %s (%q)", ErrOrigin, obj.ErrorNumber, obj.ErrorCode, obj.Error) + return "", time.Time{}, fmt.Errorf("get nucleus token: %w: error %s: %s (%q)", ErrOrigin, obj.ErrorNumber, obj.ErrorCode, obj.Error) } - return "", fmt.Errorf("get nucleus token: request %q: response status %d (%s)", resp.Request.URL.String(), resp.StatusCode, resp.Status) + return "", time.Time{}, fmt.Errorf("get nucleus token: request %q: response status %d (%s)", resp.Request.URL.String(), resp.StatusCode, resp.Status) } var obj struct { @@ -462,12 +463,19 @@ func GetNucleusToken(ctx context.Context, sid SID) (NucleusToken, error) { ExpiresIn json.Number `json:"expires_in"` } if err := json.Unmarshal(buf, &obj); err != nil { - return "", fmt.Errorf("get nucleus token: %w", err) + return "", time.Time{}, fmt.Errorf("get nucleus token: %w", err) + } + if obj.AccessToken == "" || obj.ExpiresIn == "" { + return "", time.Time{}, fmt.Errorf("get nucleus token: invalid response %q", string(buf)) } - if obj.AccessToken == "" { - return "", fmt.Errorf("get nucleus token: invalid response %q", string(buf)) + + var expiry time.Time + if v, err := obj.ExpiresIn.Int64(); err == nil { + expiry = time.Now().Add(time.Duration(v) * time.Second) + } else { + return "", time.Time{}, fmt.Errorf("get nucleus token: invalid response %q: invalid expiry: %w", string(buf), err) } - return NucleusToken(obj.AccessToken), nil + return NucleusToken(obj.AccessToken), expiry, nil } // generateCID generates a login nonce using the algorithm in the Origin login |
