@gchen,
It looks like the issue is in your refresh endpoint on duplicacy.com. Here’s a minimal example to repro the issue. Though you have to leave it running for > 4hrs. Excuse my crappy go code…haven’t written basically anything in Go before.
package main
import (
"fmt"
"os"
"time"
"github.com/gilbertchen/go-dropbox"
)
func main() {
if len(os.Args) < 2 {
fmt.Printf("\nUsage: %s REFRESH_TOKEN DO_FIX\n\n REFRESH_TOKEN: Your refresh token\n DO_FIX: true if you want to try the fix else blank to run as duplicacy does refresh.\n\n", os.Args[0])
os.Exit(1)
}
var refreshToken = os.Args[1]
// Create a client same way as in duplicacy_dropboxstorage.go
client := dropbox.NewFiles(dropbox.NewConfig("", refreshToken, "https://duplicacy.com/dropbox_refresh"))
lastToken := client.Token
iter := 0
for {
fmt.Printf("[%s]: Running iteration %d\n", time.Now().String(), iter)
iter += 1
// Make a request just to have go-dropbox create the access token.
input := &dropbox.ListFolderInput{
Path: "/",
Recursive: false,
IncludeMediaInfo: false,
IncludeDeleted: false,
}
_, err := client.ListFolder(input)
if err != nil {
fmt.Printf("Error! %+v\n", err)
}
if client.Token.AccessToken != lastToken.AccessToken {
lastToken = client.Token
fmt.Printf("Token changed at %s\n", time.Now().String())
// Write out some debugging showing the token...
fmt.Printf("Token: %+v\n", client.Client.Token)
}
if !client.Client.Token.Valid() {
fmt.Printf("Token is NOT valid.\n")
// Write out some debugging showing the token...
fmt.Printf("Token: %+v\n", client.Client.Token)
}
time.Sleep(5 * time.Second)
}
}
This yields this after the access token expires (I’ve redacted my refresh and access tokens):
[2022-11-25 23:58:49.926520839 -0500 EST m=+0.000501734]: Running iteration 0
Token changed at 2022-11-25 23:58:50.628571718 -0500 EST m=+0.702552613
Token: {AccessToken:<REDACTED> TokenType:bearer RefreshToken:<REDACTED> Expiry:2022-11-26 08:58:50.207224835 +0000 UTC raw:<nil>} 100% 6608KB 11.0MB/s 00:00
[2022-11-25 23:58:55.630222593 -0500 EST m=+5.704203489]: Running iteration 1
[2022-11-25 23:59:00.822184954 -0500 EST m=+10.896165845]: Running iteration 2
[2022-11-25 23:59:06.002938476 -0500 EST m=+16.076919386]: Running iteration 3
[2022-11-25 23:59:11.262870557 -0500 EST m=+21.336851451]: Running iteration 4
...
[2022-11-26 03:58:26.470811855 -0500 EST m=+14376.544792756]: Running iteration 2645
[2022-11-26 03:58:31.656991023 -0500 EST m=+14381.730971915]: Running iteration 2646
[2022-11-26 03:58:36.842373916 -0500 EST m=+14386.916354811]: Running iteration 2647
[2022-11-26 03:58:42.035193941 -0500 EST m=+14392.109174848]: Running iteration 2648
Token is NOT valid.
Token: {AccessToken:<REDACTED> TokenType:bearer RefreshToken:<REDACTED> Expiry:2022-11-26 08:58:50.207224835 +0000 UTC raw:<nil>}
[2022-11-26 03:58:47.222186559 -0500 EST m=+14397.296167454]: Running iteration 2649
Token is NOT valid.
Token: {AccessToken:<REDACTED> TokenType:bearer RefreshToken:<REDACTED> Expiry:2022-11-26 08:58:50.207224835 +0000 UTC raw:<nil>}
[2022-11-26 03:58:52.401880041 -0500 EST m=+14402.475860948]: Running iteration 2650
2022/11/26 03:58:52 [DROPBOX_RETRY] POST https://api.dropboxapi.com/2/files/list_folder returned 401; refreshing access
token%!(EXTRA float64=0.5)
2022/11/26 03:58:52 [DROPBOX_RETRY] POST https://api.dropboxapi.com/2/files/list_folder returned 401; refreshing access
token%!(EXTRA float64=0.5)
2022/11/26 03:58:53 [DROPBOX_RETRY] POST https://api.dropboxapi.com/2/files/list_folder returned 401; refreshing access
token%!(EXTRA float64=0.5)
From the logs you can see from the Expiry
, the access token didn’t actually change after the refresh. I verified that just setting client.Token.AccessToken
to ""
before setting the body for the refresh call allows your refresh endpoint to properly refresh the endpoint. Not sure what you’re doing on that refresh page, but if you’re just checking for the existence of AccessToken
instead of checking if the Expiry
is in the past then it would explain this behavior.
You can fix it with a one line change too the go-dropbox
code to set client.Token.AccessToken
to ""
as I mentioned above. Or, if you don’t want to do a new duplicacy version, just update that refresh page to check Expiry
and make sure to refresh if it’s in the past.
I’ll make a PR on go-dropbox
, but if you can fix the refresh page it wouldn’t require an update for everyone hitting the issue which would be nice. Also…you could just use the dropbox refresh endpoint instead though you’d have to change what you send a little.
UPDATE: Here’s the PR: Fix refreshing access token after expiration by stuckj · Pull Request #4 · gilbertchen/go-dropbox · GitHub