]> git.giacomolli.uk - onechat/blobdiff - auth.go
Serve the agent to a terminal client
[onechat] / auth.go
diff --git a/auth.go b/auth.go
index 1908b89507bc62f210a38679713cb825434462d5..fda78d8ac709473f20a0a559506e0652b220e7ba 100644 (file)
--- a/auth.go
+++ b/auth.go
@@ -63,7 +63,6 @@ type chatgptAuth struct {
        path   string
        issuer string
        http   *http.Client
-       clock  func() time.Time
 }
 
 // tokenFile is the content of the token file.
@@ -98,13 +97,23 @@ type deviceGrant struct {
 }
 
 // login runs "onechat login": the device code login into the token file of the
-// data directory.
-func login(ctx context.Context, out io.Writer) error {
+// data directory. It holds the lock of the token file, so it does not run while
+// the daemon runs.
+func login(ctx context.Context, out io.Writer) (err error) {
        dir, err := dataDir()
        if err != nil {
                return err
        }
 
+       tokens, err := lockTokens(dir)
+       if err != nil {
+               return err
+       }
+
+       defer func() {
+               err = errors.Join(err, tokens.Close())
+       }()
+
        return newChatGPTAuth(filepath.Join(dir, tokenFileName), authIssuer).Login(ctx, out)
 }
 
@@ -115,7 +124,6 @@ func newChatGPTAuth(path, issuer string) *chatgptAuth {
                path:   path,
                issuer: issuer,
                http:   &http.Client{},
-               clock:  time.Now,
        }
 }
 
@@ -308,7 +316,7 @@ func (a *chatgptAuth) Authorize(ctx context.Context, header http.Header) error {
        }
 
        expiry, found := tokenExpiry(tokens.AccessToken)
-       if !found || !a.clock().Before(expiry.Add(-refreshMargin)) {
+       if !found || !time.Now().Before(expiry.Add(-refreshMargin)) {
                tokens, err = a.refresh(ctx, tokens)
                if err != nil {
                        return err