makeWebRequest is caching/overriding redirect_uri param after call to makeOauthRequest?

Environment

  • Garmin Edge 1030+ (Software version: 6.75)
  • Connect IQ SDK version: 6.4.2
  • VS Code Extension version: v1.0.10
  • VS Code version: 1.87.2

I'm implementing an oauth flow with the spotify api using the PKCE flow and running into a strange bug. The flow is made up of these steps:

  1. makeOauthRequest to accounts.spotify.com/authorize
  2. login via garmin connect mobile app in webview
  3. receive response code
  4. makeWebRequest to accounts.spotify.com/api/token to get access token

I previously implemented this flow using the non-PKCE flow (same steps, with slightly varied params) and it worked fine. UPDATE: I just re-built the old non-PKCE code and it no longer works as it's now suffering from the same redirect_uri override issue. I guess this implies something changed in the firmware or Garmin Connect mobile app that introduced this bug?

The redirect_uri parameter that was used in the /authorize GET request needs to also be sent in the /api/token POST request and they need to match. The bug I'm running into is that despite using http://localhost as the redirect_uri value in both requests, the /api/token request in step 4 seems to have its redirect_uri param forcibly overridden with a value of gcm://oauth.

When I change the host value of the /api/token request to something else, the redirect_uri param is sent as expected with the http://localhost value, so it seems like something in the underlying http framework is getting cached around the accounts.spotify.com host.

Example /authorize call

var RedirectUri = "http://localhost"
var params = {
        "client_id"=>$.ClientId,
        "response_type"=>"code",
        "scope"=>"user-modify-playback-state,user-read-playback-state,user-read-currently-playing,playlist-read-private,user-library-modify",
        "redirect_uri"=>$.RedirectUri,
        "state"=>_state,
        "code_challenge_method"=>"S256",
        "code_challenge"=>sanitizedChallenge
};
Comm.makeOAuthRequest(
    "https://accounts.spotify.com/authorize",
    params,
    $.RedirectUri,
    Comm.OAUTH_RESULT_TYPE_URL,
    {"code"=>"code", "state"=>"state"}
);

Payload sniffed from garmin connect app

Example subsequent /api/token call with makeWebRequest, where redirect_uri gets overriden

Comm.makeWebRequest(
    "http://accounts.spotify.com/api/token",
    {
        "code"=>accessCode,
        "redirect_uri"=>"http://localhost",
        "grant_type"=>"authorization_code",
        "client_id"=>$.ClientId,
        "code_verifier"=>_codeVerifier
    },
    {
        :method => Comm.HTTP_REQUEST_METHOD_POST,
        :headers => {"Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED}
    },
    method(:handleAccessResponse)
);

Payload sniffed from garmin connect app (notice that the redirect_uri in payload gets set to gcm://oauth despite it being set to http://localhost in the code)