davmail icon indicating copy to clipboard operation
davmail copied to clipboard

Refresh Token does not update after the initial save

Open mitechzone opened this issue 3 years ago • 8 comments

It seems DavMail does not update the persisted refresh token after it was initially saved. Consequently, the refresh token expires every 90 days or so.

According to Microsoft documentation

whenever a refresh token is used to acquire a new access token, a new refresh token is also issued.

Essentially, when the grant_type is refresh_token, the returned JSON response includes a new refresh_token. Although the original refresh token isn't revoked, the new refresh token has a refreshed lifetime.

It seems that setJsonToken in O365Token does parse this updated refresh_token, but it doesn't save the new refresh token. Is it possible to change this behavior?

mitechzone avatar Mar 23 '22 17:03 mitechzone

I can contribute $100 (USD) toward a bounty to fix this.

cwarden avatar Aug 17 '22 14:08 cwarden

@mitechzone @cwarden : mguessan implemented refresh token updates in a couple recent commits. You should try them out and see if it resolves your issues. (The trunk builds from appveyor have the patches: https://github.com/mguessan/davmail )

tmcqueen-materials avatar Jan 14 '23 17:01 tmcqueen-materials

In my case, storing the new refresh token received upon refresh doesn't solve the problem because it expires at the same time as the original refresh token as described in https://github.com/mguessan/davmail/pull/238#issuecomment-1276066527.

To avoid session expiration, I'm stuck updating [email protected] in davmail.properties from outside of davmail and restarting davmail.

cwarden avatar Jan 14 '23 17:01 cwarden

It hasn't been 90 days yet, but the patch from @piyushgarg seems to have reduced the frequency I needed to manually update the token. Previously, I had to update the token every other week. With the patch, I haven't manually updated the token since November. I'll try the new update, but it will take a while to confirm.

mitechzone avatar Jan 14 '23 21:01 mitechzone

I installed the latest development version of davmail on my Ubuntu 22.04 machine on January 14, but my token still expired at the 90 day mark like it usually does. I'm not sure why one message below says that it was inactive for 90 days, as it was not. But it wasn't used in the day or two before expiry, in case that matters. (I only use davmail for outgoing mail on that machine, and didn't send any messages from it recently.)

I do have davmail.oauth.persistToken=true in my config file.

2023-01-30 09:19:04,899 INFO  [davmail.smtp.SmtpServer] davmail.connection  - CONNECT - 127.0.0.1:32878 
2023-01-30 09:19:06,562 ERROR [SmtpConnection-32878] davmail.exchange.auth.O365Token  - refresh token failed invalid_grant AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2022-11-01T13:15:35.5309537Z and was inactive for 90.00:00:00.
Trace ID: 4770db56-b993-43bf-b657-1e9c577dcf00
Correlation ID: 58804365-98b9-467f-87a1-f7fafb3684ef
Timestamp: 2023-01-30 14:19:06Z
2023-01-30 09:19:06,575 ERROR [SmtpConnection-32878] davmail.exchange.auth.O365ManualAuthenticator  - Authentication failed, code not available
2023-01-30 09:19:06,576 INFO  [SmtpConnection-32878] davmail.connection  - FAILED - 127.0.0.1:32878 [email protected]
2023-01-30 09:19:06,578 ERROR [SmtpConnection-32878] davmail  - Authentication failed null
davmail.exception.DavMailException: Authentication failed null
        at davmail.exchange.auth.O365ManualAuthenticator.authenticate(O365ManualAuthenticator.java:120)
        at davmail.exchange.ExchangeSessionFactory.getInstance(ExchangeSessionFactory.java:182)
        at davmail.exchange.ExchangeSessionFactory.getInstance(ExchangeSessionFactory.java:93)
        at davmail.smtp.SmtpConnection.authenticate(SmtpConnection.java:229)
        at davmail.smtp.SmtpConnection.run(SmtpConnection.java:106)
2023-01-30 09:19:06,586 INFO  [SmtpConnection-32878] davmail.connection  - DISCONNECT - 127.0.0.1:32878 

On another Ubuntu 22.04 machine, it looks like the token is going to expire in about a hour:

2023-01-30 09:35:09,830 DEBUG [ImapConnection-57302] davmail.exchange.auth.O365Token  - Access token expires Mon Jan 30 10:38:23 EST 2023

Is there anything I should watch for here? On this machine, I'm polling for new mail every 30 seconds.

From the code, it looks like davmail only requests a new token if it is within 60 seconds of expiry? Is that right?

jdchristensen avatar Jan 30 '23 14:01 jdchristensen

From the code, it looks like davmail only requests a new token if it is within 60 seconds of expiry? Is that right?

I think that it requests new tokens when the access token is within 60 seconds of expiry (or has expired), which should happen every hour. We should receive a new refresh token as well at the same time, which should be stored. I added some comments to the commit about logging some information that might help debug this.

jdchristensen avatar Jan 30 '23 15:01 jdchristensen

Machine 2 (which does frequent polling) is still able to connect to Office 365, after 91 days, so something seems to be working better there. Not sure why Machine 1 had its token expire. The main differences are: Machine 1 only uses davmail for outgoing mail, and only occasionally, while Machine 2 uses davmail for incoming and outgoing mail, and polls frequently (every 30s) for incoming mail.

jdchristensen avatar Jan 31 '23 13:01 jdchristensen

Ok, I checked through my logs and found that I didn't send a single message from Machine 1 since upgrading davmail with the new code, so davmail never asked for a new access token and therefore never got a new refresh token. Sorry for the noise, I think this is working correctly.

One idea: davmail could keep track of the expiry date on the refresh token, and make sure to renew it well in advance, say a week ahead or a month ahead. It's a rare situation, so maybe isn't worth it.

jdchristensen avatar Jan 31 '23 20:01 jdchristensen