FlowCrypt / flowcrypt-browser

FlowCrypt Browser extension for Chrome and Firefox
https://flowcrypt.com
Other
375 stars 46 forks source link

Check Google id token expiration before usage #5691

Closed sosnovsky closed 4 months ago

sosnovsky commented 5 months ago

Sometimes in browser extension console logs I see error:

webmail_bundle.js:49 BrowserMsg(ajax) Unauthorized: 401 when GET-ing https://..../keys/private (no body):  -> No matching authenticator found for Authorization starting with Bearer eyJhbGciOiJSUzI1NiIsImt...

[callerStack]
    at BrowserMsg.sendRaw (chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:10292:26)
    at BrowserMsg.sendAwait (chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:10280:37)
    at Object.ajax (chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:10435:38)
    at Api.ajax (chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:7334:55)
    at Api.apiCall (chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:7642:34)
    at KeyManager.getPrivateKeys (chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:7879:34)
    at chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:16058:78
    at chrome-extension://pjohdcpiapjhagmakkjpgjmodmgfmkkd/js/content_scripts/webmail_bundle.js:93:27

I checked backend logs and found reason for mentioned error

Client error: 401 Unauthorized GET http://[127.0.0.1]/v1/keys/private | id: a1bc06e10319 | message: authentication:
The JWT is no longer valid - the evaluation time NumericDate{1714160438 -> Apr 26, 2024, 7:40:38 PM UTC} is on or after the Expiration Time (exp=NumericDate{1714159800 -> Apr 26, 2024, 7:30:00 PM UTC}) claim value (even when providing 30 seconds of leeway to account for clock skew).

Currently we don't have check for id token expiration time, so let's check if id token has expired before using it and expired tokens should be refreshed before using.

ioanmo226 commented 4 months ago

@sosnovsky, I think we can streamline the token refresh logic by moving it from ExternalService.request to Api.ApiCall. How about we add a try-catch block in Api.ApiCall like ExternalSerivce.request? This way, if a call fails due to a 401 unauthorized error, it automatically tries to refresh the access token and attempts the call again to resolve the issue. What do you think?

https://github.com/FlowCrypt/flowcrypt-browser/blob/e6a1d4739f60c0daaa2dda6aef898ad082b9cdc5/extension/js/common/api/account-servers/external-service.ts#L200

sosnovsky commented 4 months ago

Sounds good, let's try this solution