From 501f32ce84ac33e21db39ea88fa3927540ceca4a Mon Sep 17 00:00:00 2001 From: anguriskit24 <138706940+anguriskit24@users.noreply.github.com> Date: Fri, 11 Aug 2023 15:58:32 -0500 Subject: [PATCH 1/2] Replace existing cookies with new cookies from response. Also, corrected cookie name equals check in deleteCookie(). --- .../carelink/client/SimpleOkHttpCookieJar.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/info/nightscout/medtronic/carelink/client/SimpleOkHttpCookieJar.java b/src/main/java/info/nightscout/medtronic/carelink/client/SimpleOkHttpCookieJar.java index c02f140..5d7213d 100644 --- a/src/main/java/info/nightscout/medtronic/carelink/client/SimpleOkHttpCookieJar.java +++ b/src/main/java/info/nightscout/medtronic/carelink/client/SimpleOkHttpCookieJar.java @@ -13,7 +13,14 @@ public class SimpleOkHttpCookieJar implements CookieJar { @Override public void saveFromResponse(HttpUrl url, List cookies) { - storage.addAll(cookies); + + // Replace cookie if already exists + for (Cookie cookie : cookies) { + if (contains(cookie.name())) { + deleteCookie(cookie.name()); + } + storage.add(cookie); + } } @Override @@ -58,7 +65,7 @@ public boolean contains(String name) { public void deleteCookie(String name) { for (int i = 0; i < storage.size(); i++) { - if(storage.get(i).name() == name) { + if(storage.get(i).name().equals(name)) { storage.remove(i); } } From 22defbd961a5092c7ed40f3f64adc0170928df39 Mon Sep 17 00:00:00 2001 From: anguriskit24 <138706940+anguriskit24@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:01:18 -0500 Subject: [PATCH 2/2] Get new auth token if existing token is nearing expiration instead of attempting new login. --- .../carelink/client/CareLinkClient.java | 71 ++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/src/main/java/info/nightscout/medtronic/carelink/client/CareLinkClient.java b/src/main/java/info/nightscout/medtronic/carelink/client/CareLinkClient.java index 287739f..c3b18d0 100644 --- a/src/main/java/info/nightscout/medtronic/carelink/client/CareLinkClient.java +++ b/src/main/java/info/nightscout/medtronic/carelink/client/CareLinkClient.java @@ -16,10 +16,15 @@ public class CareLinkClient { protected static final String CARELINK_CONNECT_SERVER_EU = "carelink.minimed.eu"; protected static final String CARELINK_CONNECT_SERVER_US = "carelink.minimed.com"; + protected static final String CARELINK_LOGIN_SERVER_EU = "mdtlogin-ocl.medtronic.com"; + protected static final String CARELINK_LOGIN_SERVER_US = "mdtlogin.medtronic.com"; + protected static final String CARELINK_LANGUAGE_EN = "en"; protected static final String CARELINK_LOCALE_EN = "en"; - protected static final String CARELINK_AUTH_TOKEN_COOKIE_NAME = "auth_tmp_token"; - protected static final String CARELINK_TOKEN_VALIDTO_COOKIE_NAME = "c_token_valid_to"; + public static final String CARELINK_AUTH_TOKEN_COOKIE_NAME = "auth_tmp_token"; + public static final String CARELINK_TOKEN_VALIDTO_COOKIE_NAME = "c_token_valid_to"; + protected static final String CARELINK_AUTH_PATH_SEGMENT = "patient/sso/reauth"; + protected static final String CARELINK_LOGIN_PATH_SEGMENT = "patient/sso/login"; protected static final int AUTH_EXPIRE_DEADLINE_MINUTES = 1; //Authentication data @@ -71,7 +76,7 @@ protected void setLastResponseBody(Response response){ } catch (Exception ex){} } protected void setLastResponseBody(String responseBody){ - this.lastResponseBody = responseBody; + this.lastResponseBody = responseBody; } public String getLastResponseBody(){ return lastResponseBody; @@ -137,9 +142,13 @@ public RecentData getRecentData() { // Get server URL protected String careLinkServer() { - return this.carelinkCountry.equals("us") ? CARELINK_CONNECT_SERVER_US : CARELINK_CONNECT_SERVER_EU; + return this.carelinkCountry.equals("us") ? CARELINK_CONNECT_SERVER_US : CARELINK_CONNECT_SERVER_EU; } + // Get login server URL + protected String careLinkLoginServer() { + return this.carelinkCountry.equals("us") ? CARELINK_LOGIN_SERVER_US : CARELINK_LOGIN_SERVER_EU; + } // Authentication methods public boolean login(){ @@ -216,7 +225,7 @@ protected Response getLoginSession() throws IOException { HttpUrl url = null; Request.Builder requestBuilder = null; - url = new HttpUrl.Builder().scheme("https").host(this.careLinkServer()).addPathSegments("patient/sso/login") + url = new HttpUrl.Builder().scheme("https").host(this.careLinkServer()).addPathSegments(CARELINK_LOGIN_PATH_SEGMENT) .addQueryParameter("country", this.carelinkCountry).addQueryParameter("lang", CARELINK_LANGUAGE_EN) .build(); @@ -244,7 +253,7 @@ protected Response doLogin(Response loginSessionResponse) throws IOException { .add("actionButton", "Log in") .build(); - url = new HttpUrl.Builder().scheme("https").host("mdtlogin.medtronic.com") + url = new HttpUrl.Builder().scheme("https").host(this.careLinkLoginServer()) .addPathSegments("mmcl/auth/oauth/v2/authorize/login").addQueryParameter("locale", CARELINK_LOCALE_EN) .addQueryParameter("country", this.carelinkCountry).build(); @@ -284,6 +293,50 @@ protected Response doConsent(Response doLoginResponse) throws IOException { } + protected void getNewAuthorizationToken() { + + // Get existing auth token + String authToken = ((SimpleOkHttpCookieJar) httpClient.cookieJar()).getCookies(CARELINK_AUTH_TOKEN_COOKIE_NAME).get(0).value(); + + if (authToken != null) { + + authToken = "Bearer" + " " + authToken; + + Response reauthResponse = null; + Request.Builder requestBuilder = null; + + HttpUrl url = new HttpUrl.Builder().scheme("https").host(this.careLinkServer()) + .addPathSegments(CARELINK_AUTH_PATH_SEGMENT).addQueryParameter("locale", CARELINK_LOCALE_EN) + .addQueryParameter("country", this.carelinkCountry).build(); + + // Create request for URL with authToken + requestBuilder = new Request.Builder().url(url).addHeader("Authorization", authToken); + + RequestBody requestBody = null; + Gson gson = null; + JsonObject userJson = null; + + // Build user json for request + userJson = new JsonObject(); + gson = new GsonBuilder().create(); + + requestBody = RequestBody.create(gson.toJson(userJson), MediaType.get("application/json; charset=utf-8")); + + requestBuilder.post(requestBody); + this.addHttpHeaders(requestBuilder, RequestType.HtmlPost); + + try { + reauthResponse = this.httpClient.newCall(requestBuilder.build()).execute(); + } + catch (IOException e) { + lastErrorMessage = e.getMessage(); + } + finally { + reauthResponse.close(); + } + } + } + protected String getAuthorizationToken() { // New token is needed: @@ -297,10 +350,12 @@ protected String getAuthorizationToken() { + AUTH_EXPIRE_DEADLINE_MINUTES * 60000))) || this.lastResponseCode == 401 ) { + //execute new login process | null, if error OR already doing login - if(this.loginInProcess || !this.executeLoginProcedure()) + if(this.loginInProcess) return null; - + else + getNewAuthorizationToken(); } // there can be only one