aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpg9182 <96569817+pg9182@users.noreply.github.com>2022-10-14 13:23:19 -0400
committerpg9182 <96569817+pg9182@users.noreply.github.com>2022-10-14 13:23:19 -0400
commit01155bde059e93700ea4b8bd47e6835b8232f57c (patch)
tree2d7c337aeb9e99a238986ab84300399fe36fdbb6
parent04096e175a60ffaf247a03f5cb9d94909e7409c2 (diff)
downloadAtlas-01155bde059e93700ea4b8bd47e6835b8232f57c.tar.gz
Atlas-01155bde059e93700ea4b8bd47e6835b8232f57c.zip
pkg/origin, cmd/origin-login-test: Return nucleus token expiry
-rw-r--r--cmd/origin-login-test/main.go6
-rw-r--r--pkg/origin/login.go34
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