From b711e4a1c5ddb6006f4879869a15624bf94395ec Mon Sep 17 00:00:00 2001 From: Kiran Ayyagari Date: Tue, 20 May 2025 15:03:53 +0530 Subject: [PATCH 01/10] Added install4j configuration file (#81) Signed-off-by: kayyagari --- .../install4j/oie-installer-config.install4j | 750 ++++++++++++++++++ 1 file changed, 750 insertions(+) create mode 100644 tools/install4j/oie-installer-config.install4j diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j new file mode 100644 index 000000000..fc5d86700 --- /dev/null +++ b/tools/install4j/oie-installer-config.install4j @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # +# Do not modify this file! It may get overwritten in an update. Please put all custom +# options in custom.vmoptions +# +-server +-Xmx256m +-Djava.awt.headless=true +-Dapple.awt.UIElement=true + + + + + + + + + + + + + + # +# Do not modify this file! It may get overwritten in an update. Please put all custom +# options in custom.vmoptions +# +-server +-Xmx256m +-Djava.awt.headless=true +-Dapple.awt.UIElement=true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 255 + 255 + 255 + 255 + + + 49 + 52 + 53 + 255 + + + + + + + + + + + + + icon:${installer:sys.installerApplicationMode}_header.png + + + + + 0 + 5 + 1 + 1 + + + + + 0 + 20 + 0 + 10 + + + + + backgroundColor + foregroundColor + imageAnchor + imageFile + imageOverlap + + + + + + + + + sys.installationDir + + + context.getBooleanVariable("sys.confirmedUpdateInstallation") + + + + + + ${form:welcomeMessage} + + !context.isConsole() + + + + + + String message = context.getMessage("ConsoleWelcomeLabel", context.getApplicationName()); +return console.askOkCancel(message, true); + + + + + + + + updateCheck + + + + + ${i18n:ClickNext} + + + + + + + + + ${i18n:LicenseLabel3} + + + + + + + + en + + ${compiler:installer:mediaRoot}/server/setup/docs/LICENSE.txt + + + + + + license + + + textSource + displayedText + displayedTextFile + variableName + acceptInitiallySelected + readAllRequired + + + + + + + + + ${i18n:InfoBeforeClickLabel} + + !context.isConsole() + + + + <!DOCTYPE html> +<html> +<body style="font-family: Arial, sans-serif; line-height: 1.6; margin: 1em; background-color: white; color: black;"> + <h1 style="color: black;">Open Integration Engine - Preview Release</h1> + <p>This is a preview release of the Open Integration Engine.</p> + <p> + This release is recommended for users already familiar with Mirth Connect. + It installs a fully functional version of the engine with minimal prompts. + </p> + <h2>Notes</h2> + <ul> + <li>Native services are installed for all supported platforms and are configured to start automatically.</li> + <li><strong>macOS users:</strong> A reboot will automatically start the service.</li> + <li> + Default settings from mirth.properties are applied automatically; the installer does not prompt for customization. + </li> + <li>This includes ports (default: 8080 and 8443), log and app data paths, and password requirements.</li> + <li> + Previous installations are not preserved, though runtime-created directories + (e.g., appdata) + are retained across installs. + </li> + + </ul> +</body> +</html> + + + + + + textSource + displayedText + displayedTextFile + variableName + + + + + + + console.waitForEnter(); +return true; + + + + + + + + + !context.getBooleanVariable("sys.confirmedUpdateInstallation") + + + + + sys.installationDir + + + context.getVariable("sys.responseFile") == null + + + + + + ${i18n:SelectDirLabel(${compiler:sys.fullName})} + + + + + + + + suggestAppDir + validateApplicationId + existingDirWarning + checkWritable + manualEntryAllowed + checkFreeSpace + showRequiredDiskSpace + showFreeDiskSpace + allowSpacesOnUnix + validationScript + standardValidation + + + + + + + + + ${i18n:SelectComponentsLabel2} + + !context.isConsole() + + + + + + + selectionChangedScript + + + + + + + + + + + + + + + + + + ${i18n:UninstallerMenuEntry(${compiler:sys.fullName})} + + !context.getBooleanVariable("sys.programGroupDisabled") + + + + ${compiler:sys.fullName} ${compiler:sys.version} + + + + + 25 + com.oie.oieservice + + + + + + + ${compiler:sys.fullName} Server.vmoptions + + + # Lines begining with a # are ignored as comments. +# Do not add customizations to this file. + +-include-options conf/base_includes.vmoptions + +# Comment out the following line if you are running on Java 8 +-include-options conf/default_modules.vmoptions + +# Put any custom options in the following file +-include-options conf/custom.vmoptions + + + + + + + ${compiler:sys.fullName} Server.vmoptions + + + # Lines begining with a # are ignored as comments. +# Do not add customizations to this file. + +-include-options conf/base_includes.vmoptions + +# Comment out the following line if you are running on Java 8 +-include-options conf/default_modules.vmoptions + +# Put any custom options in the following file +-include-options conf/custom.vmoptions + + + + + + + ${i18n:WizardPreparing} + + + + + + + + + ${form:finishedMessage} + + + + + + + + + ${i18n:UninstallerMenuEntry(${compiler:sys.fullName})} + + + + + + + + + + + + + + + + ${form:welcomeMessage} + + !context.isConsole() + + + + + + String message = context.getMessage("ConfirmUninstall", context.getApplicationName()); +return console.askYesNo(message, true); + + + + + + + + + + + + + + + ${i18n:UninstallerPreparing} + + + + + + + + + + ${form:successMessage} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 19b1501cd65dc7108dc72e599602f05f10d5f16f Mon Sep 17 00:00:00 2001 From: kayyagari Date: Mon, 26 May 2025 20:07:14 +0530 Subject: [PATCH 02/10] Replaced macOS universal installer with Aarch and x86 installers --- tools/install4j/oie-installer-config.install4j | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j index fc5d86700..18efffd2f 100644 --- a/tools/install4j/oie-installer-config.install4j +++ b/tools/install4j/oie-installer-config.install4j @@ -726,6 +726,9 @@ return console.askYesNo(message, true); + + + @@ -733,15 +736,27 @@ return console.askYesNo(message, true); - + + + + + + + + + + + + + From c930a94b64f93f11800fa360b673959647f40efa Mon Sep 17 00:00:00 2001 From: kayyagari Date: Thu, 29 May 2025 07:38:33 +0530 Subject: [PATCH 03/10] Set Java17 as the default JRE --- tools/install4j/oie-installer-config.install4j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j index 18efffd2f..3c94b8b6f 100644 --- a/tools/install4j/oie-installer-config.install4j +++ b/tools/install4j/oie-installer-config.install4j @@ -1,11 +1,11 @@ - + - + From effb0a8809e7629da58e332aee2164ea41f15d8c Mon Sep 17 00:00:00 2001 From: kayyagari Date: Sun, 1 Jun 2025 21:18:54 +0530 Subject: [PATCH 04/10] Integrated changes made by Paul --- .../install4j/oie-installer-config.install4j | 90 +++++++++---------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j index 3c94b8b6f..276561c4e 100644 --- a/tools/install4j/oie-installer-config.install4j +++ b/tools/install4j/oie-installer-config.install4j @@ -16,7 +16,31 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -81,13 +105,14 @@ - + - - + + + @@ -245,6 +270,7 @@ return console.askOkCancel(message, true); <p> This release is recommended for users already familiar with Mirth Connect. It installs a fully functional version of the engine with minimal prompts. + As you have seen - this does require admin permissions to run and install services, we will be updating that! </p> <h2>Notes</h2> <ul> @@ -365,50 +391,12 @@ return true; ${compiler:sys.fullName} ${compiler:sys.version} - + 25 com.oie.oieservice - - - - - ${compiler:sys.fullName} Server.vmoptions - - - # Lines begining with a # are ignored as comments. -# Do not add customizations to this file. - --include-options conf/base_includes.vmoptions - -# Comment out the following line if you are running on Java 8 --include-options conf/default_modules.vmoptions - -# Put any custom options in the following file --include-options conf/custom.vmoptions - - - - - - - ${compiler:sys.fullName} Server.vmoptions - - - # Lines begining with a # are ignored as comments. -# Do not add customizations to this file. - --include-options conf/base_includes.vmoptions - -# Comment out the following line if you are running on Java 8 --include-options conf/default_modules.vmoptions - -# Put any custom options in the following file --include-options conf/custom.vmoptions - - @@ -725,22 +713,23 @@ return console.askYesNo(message, true); - + - + + - + @@ -755,11 +744,16 @@ return console.askYesNo(message, true); - + + + + + + + - From 04e90d856118c6ad7049bf082f5dfcab36df301e Mon Sep 17 00:00:00 2001 From: kayyagari Date: Mon, 2 Jun 2025 17:27:06 +0530 Subject: [PATCH 05/10] Added media that bundles JRE --- .../install4j/oie-installer-config.install4j | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j index 276561c4e..5bdd2d957 100644 --- a/tools/install4j/oie-installer-config.install4j +++ b/tools/install4j/oie-installer-config.install4j @@ -752,8 +752,38 @@ return console.askYesNo(message, true); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7247f5b19b8c842b184f4136213695d1bb74af8d Mon Sep 17 00:00:00 2001 From: kayyagari Date: Mon, 2 Jun 2025 18:12:33 +0530 Subject: [PATCH 06/10] Changed the configuration to remove vmoptions files of oieserver and oieservice during uninstallation --- tools/install4j/oie-installer-config.install4j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j index 5bdd2d957..e897b57a3 100644 --- a/tools/install4j/oie-installer-config.install4j +++ b/tools/install4j/oie-installer-config.install4j @@ -18,8 +18,6 @@ - - @@ -29,6 +27,7 @@ + @@ -38,6 +37,7 @@ + From 087ebf17d1b22cd5ee796dbc231b4609f7529700 Mon Sep 17 00:00:00 2001 From: kelaompachai <141376761+kelaompachai@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:50:47 -0400 Subject: [PATCH 07/10] Update client notifications to pull from github Release API - Added library java-semver-0.10.2.jar for version parsing and comparison. - Refactored to use streams and added tests - No longer calls a self-hosted service, so active extensions are no longer provided as part of the request. Co-authored-by: Richard Ogin Co-authored-by: Jon Bartels Co-authored-by: Tony Germano Signed-off-by: kelaompachai <141376761+kelaompachai@users.noreply.github.com> Signed-off-by: Richard Ogin Signed-off-by: Tony Germano Issue: https://github.com/OpenIntegrationEngine/engine/issues/24 --- client/.classpath | 1 + client/lib/java-semver-0.10.2.jar | Bin 0 -> 52003 bytes server/.classpath | 9 +- server/build.xml | 1 + server/lib/java-semver-0.10.2.jar | Bin 0 -> 52003 bytes .../client/core/ConnectServiceUtil.java | 214 +-- .../client/core/ConnectServiceUtilTest.java | 224 ++++ .../test/resources/notifications-empty.json | 3 + .../resources/notifications-populated.json | 1144 +++++++++++++++++ 9 files changed, 1498 insertions(+), 98 deletions(-) create mode 100644 client/lib/java-semver-0.10.2.jar create mode 100644 server/lib/java-semver-0.10.2.jar create mode 100644 server/test/com/mirth/connect/client/core/ConnectServiceUtilTest.java create mode 100644 server/test/resources/notifications-empty.json create mode 100644 server/test/resources/notifications-populated.json diff --git a/client/.classpath b/client/.classpath index 9d31d09ea..ebaff9964 100644 --- a/client/.classpath +++ b/client/.classpath @@ -213,5 +213,6 @@ + diff --git a/client/lib/java-semver-0.10.2.jar b/client/lib/java-semver-0.10.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..875926e9ac2cf61f8acdf8d24e0fe7d0504685ad GIT binary patch literal 52003 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

-qSA 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 literal 0 HcmV?d00001 diff --git a/server/.classpath b/server/.classpath index 79310f1f0..4c107334c 100644 --- a/server/.classpath +++ b/server/.classpath @@ -5,10 +5,11 @@ + - + @@ -190,9 +191,9 @@ - - - + + + diff --git a/server/build.xml b/server/build.xml index 96830a4ec..9aa6606c1 100644 --- a/server/build.xml +++ b/server/build.xml @@ -1274,6 +1274,7 @@ + diff --git a/server/lib/java-semver-0.10.2.jar b/server/lib/java-semver-0.10.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..875926e9ac2cf61f8acdf8d24e0fe7d0504685ad GIT binary patch literal 52003 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

-qSA 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 literal 0 HcmV?d00001 diff --git a/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java b/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java index 9a6b003e7..426629f96 100644 --- a/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java +++ b/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java @@ -9,22 +9,30 @@ package com.mirth.connect.client.core; +import java.io.IOException; +import java.io.InputStreamReader; import java.net.URI; import java.nio.charset.Charset; -import java.util.ArrayList; +import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.HttpClientUtils; @@ -38,10 +46,12 @@ import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; -import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.zafarkhaja.semver.Version; import com.mirth.connect.model.User; import com.mirth.connect.model.converters.ObjectXMLSerializer; import com.mirth.connect.model.notification.Notification; @@ -51,9 +61,7 @@ public class ConnectServiceUtil { private final static String URL_CONNECT_SERVER = "https://connect.mirthcorp.com"; private final static String URL_REGISTRATION_SERVLET = "/RegistrationServlet"; private final static String URL_USAGE_SERVLET = "/UsageStatisticsServlet"; - private final static String URL_NOTIFICATION_SERVLET = "/NotificationServlet"; - private static String NOTIFICATION_GET = "getNotifications"; - private static String NOTIFICATION_COUNT_GET = "getNotificationCount"; + private static String URL_NOTIFICATIONS = "https://api.github.com/repos/openintegrationengine/engine/releases"; private final static int TIMEOUT = 10000; public final static Integer MILLIS_PER_DAY = 86400000; @@ -66,7 +74,7 @@ public static void registerUser(String serverId, String mirthVersion, User user, HttpPost post = new HttpPost(); post.setURI(URI.create(URL_CONNECT_SERVER + URL_REGISTRATION_SERVLET)); - post.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), Charset.forName("UTF-8"))); + post.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), StandardCharsets.UTF_8)); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT).setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).build(); try { @@ -87,112 +95,130 @@ public static void registerUser(String serverId, String mirthVersion, User user, } } + /** + * Query an external source for new releases. Return notifications for each release that's greater than the current version. + * + * @param serverId + * @param mirthVersion + * @param extensionVersions + * @param protocols + * @param cipherSuites + * @return a non-null list + * @throws Exception should anything fail dealing with the web request and the handling of its response + */ public static List getNotifications(String serverId, String mirthVersion, Map extensionVersions, String[] protocols, String[] cipherSuites) throws Exception { - CloseableHttpClient client = null; - HttpPost post = new HttpPost(); - CloseableHttpResponse response = null; - - List allNotifications = new ArrayList(); + List validNotifications = Collections.emptyList(); + Optional parsedMirthVersion = Version.tryParse(mirthVersion); + if (!parsedMirthVersion.isPresent()) { + return validNotifications; + } + CloseableHttpClient httpClient = null; + CloseableHttpResponse httpResponse = null; + HttpEntity responseEntity = null; try { - ObjectMapper mapper = new ObjectMapper(); - String extensionVersionsJson = mapper.writeValueAsString(extensionVersions); - NameValuePair[] params = { new BasicNameValuePair("op", NOTIFICATION_GET), - new BasicNameValuePair("serverId", serverId), - new BasicNameValuePair("version", mirthVersion), - new BasicNameValuePair("extensionVersions", extensionVersionsJson) }; RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT).setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).build(); + HttpClientContext getContext = HttpClientContext.create(); + getContext.setRequestConfig(requestConfig); + httpClient = getClient(protocols, cipherSuites); + HttpGet httpget = new HttpGet(URL_NOTIFICATIONS); + // adding header makes github send back body as rendered html for the "body_html" field + httpget.addHeader("Accept", "application/vnd.github.html+json"); + httpResponse = httpClient.execute(httpget, getContext); - post.setURI(URI.create(URL_CONNECT_SERVER + URL_NOTIFICATION_SERVLET)); - post.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), Charset.forName("UTF-8"))); + int statusCode = httpResponse.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_OK) { + responseEntity = httpResponse.getEntity(); - HttpClientContext postContext = HttpClientContext.create(); - postContext.setRequestConfig(requestConfig); - client = getClient(protocols, cipherSuites); - response = client.execute(post, postContext); - StatusLine statusLine = response.getStatusLine(); - int statusCode = statusLine.getStatusCode(); - if ((statusCode == HttpStatus.SC_OK)) { - HttpEntity responseEntity = response.getEntity(); - Charset responseCharset = null; - try { - responseCharset = ContentType.getOrDefault(responseEntity).getCharset(); - } catch (Exception e) { - responseCharset = ContentType.TEXT_PLAIN.getCharset(); - } - - String responseContent = IOUtils.toString(responseEntity.getContent(), responseCharset).trim(); - JsonNode rootNode = mapper.readTree(responseContent); - - for (JsonNode childNode : rootNode) { - Notification notification = new Notification(); - notification.setId(childNode.get("id").asInt()); - notification.setName(childNode.get("name").asText()); - notification.setDate(childNode.get("date").asText()); - notification.setContent(childNode.get("content").asText()); - allNotifications.add(notification); - } + validNotifications = toJsonStream(responseEntity) + .filter(dropOlderThan(parsedMirthVersion.get())) + .map(ConnectServiceUtil::toNotification) + .collect(Collectors.toList()); } else { throw new ClientException("Status code: " + statusCode); } - } catch (Exception e) { - throw e; } finally { - HttpClientUtils.closeQuietly(response); - HttpClientUtils.closeQuietly(client); + EntityUtils.consumeQuietly(responseEntity); + HttpClientUtils.closeQuietly(httpResponse); + HttpClientUtils.closeQuietly(httpClient); } - return allNotifications; + return validNotifications; } - public static int getNotificationCount(String serverId, String mirthVersion, Map extensionVersions, Set archivedNotifications, String[] protocols, String[] cipherSuites) { - CloseableHttpClient client = null; - HttpPost post = new HttpPost(); - CloseableHttpResponse response = null; + /** + * Creates a predicate to filter JSON nodes representing releases. + * The predicate returns true if the "tag_name" of the JSON node, when parsed as a semantic version, + * is newer than the provided reference version. + * + * @param version The reference {@link Version} to compare against + * @return A {@link Predicate} for {@link JsonNode}s that evaluates to true for newer versions. + */ + protected static Predicate dropOlderThan(Version version) { + return node -> Version.tryParse(node.get("tag_name").asText()) + .filter(version::isLowerThan) + .isPresent(); + } - int notificationCount = 0; + /** + * Converts an HTTP response entity containing a JSON array into a stream of {@link JsonNode} objects. + * Each element in the JSON array becomes a {@link JsonNode} in the stream. + * + * @param responseEntity The {@link HttpEntity} from the HTTP response, expected to contain a JSON array. + * @return A stream of {@link JsonNode} objects. + * @throws IOException If an I/O error occurs while reading the response entity. + * @throws JsonMappingException If an error occurs during JSON parsing. + */ + protected static Stream toJsonStream(HttpEntity responseEntity) throws IOException, JsonMappingException { + JsonNode rootNode = new ObjectMapper().readTree(new InputStreamReader(responseEntity.getContent(), getCharset(responseEntity))); + return StreamSupport.stream(rootNode.spliterator(), false); + } + /** + * Try pulling a charset from the given response. Default to UTF-8. + * + * @param responseEntity + * @return + */ + protected static Charset getCharset(HttpEntity responseEntity) { + Charset charset = StandardCharsets.UTF_8; try { - ObjectMapper mapper = new ObjectMapper(); - String extensionVersionsJson = mapper.writeValueAsString(extensionVersions); - NameValuePair[] params = { new BasicNameValuePair("op", NOTIFICATION_COUNT_GET), - new BasicNameValuePair("serverId", serverId), - new BasicNameValuePair("version", mirthVersion), - new BasicNameValuePair("extensionVersions", extensionVersionsJson) }; - RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT).setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).build(); + ContentType ct = ContentType.get(responseEntity); + Charset fromHeader = ct.getCharset(); + if (fromHeader != null) { + charset = fromHeader; + } + } catch (Exception ignore) {} + return charset; + } - post.setURI(URI.create(URL_CONNECT_SERVER + URL_NOTIFICATION_SERVLET)); - post.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), Charset.forName("UTF-8"))); + /** + * Given a JSON node with HTML content from a GitHub release feed, convert it to a notification. + * + * @param node + * @return a notification + */ + protected static Notification toNotification(JsonNode node) { + Notification notification = new Notification(); + notification.setId(node.get("id").asInt()); + notification.setName(node.get("name").asText()); + notification.setDate(node.get("published_at").asText()); + notification.setContent(node.get("body_html").asText()); + return notification; + } - HttpClientContext postContext = HttpClientContext.create(); - postContext.setRequestConfig(requestConfig); - client = getClient(protocols, cipherSuites); - response = client.execute(post, postContext); - StatusLine statusLine = response.getStatusLine(); - int statusCode = statusLine.getStatusCode(); - if ((statusCode == HttpStatus.SC_OK)) { - HttpEntity responseEntity = response.getEntity(); - Charset responseCharset = null; - try { - responseCharset = ContentType.getOrDefault(responseEntity).getCharset(); - } catch (Exception e) { - responseCharset = ContentType.TEXT_PLAIN.getCharset(); - } - - List notificationIds = mapper.readValue(IOUtils.toString(responseEntity.getContent(), responseCharset).trim(), new TypeReference>() { - }); - for (int id : notificationIds) { - if (!archivedNotifications.contains(id)) { - notificationCount++; - } - } - } - } catch (Exception e) { - } finally { - HttpClientUtils.closeQuietly(response); - HttpClientUtils.closeQuietly(client); + public static int getNotificationCount(String serverId, String mirthVersion, Map extensionVersions, Set archivedNotifications, String[] protocols, String[] cipherSuites) { + Long notificationCount = 0L; + try { + notificationCount = getNotifications(serverId, mirthVersion, extensionVersions, protocols, cipherSuites) + .stream() + .map(Notification::getId) + .filter(id -> !archivedNotifications.contains(id)) + .count(); + } catch (Exception ignore) { + System.err.println("Failed to get notification count, defaulting to zero: " + ignore); } - return notificationCount; + return notificationCount.intValue(); } public static boolean sendStatistics(String serverId, String mirthVersion, boolean server, String data, String[] protocols, String[] cipherSuites) { @@ -212,7 +238,7 @@ public static boolean sendStatistics(String serverId, String mirthVersion, boole RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT).setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).build(); post.setURI(URI.create(URL_CONNECT_SERVER + URL_USAGE_SERVLET)); - post.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), Charset.forName("UTF-8"))); + post.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), StandardCharsets.UTF_8)); try { HttpClientContext postContext = HttpClientContext.create(); diff --git a/server/test/com/mirth/connect/client/core/ConnectServiceUtilTest.java b/server/test/com/mirth/connect/client/core/ConnectServiceUtilTest.java new file mode 100644 index 000000000..d5061313f --- /dev/null +++ b/server/test/com/mirth/connect/client/core/ConnectServiceUtilTest.java @@ -0,0 +1,224 @@ +package com.mirth.connect.client.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.apache.http.HttpEntity; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.message.BasicHeader; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.zafarkhaja.semver.Version; +import com.mirth.connect.model.notification.Notification; + +public class ConnectServiceUtilTest { + private static final String FILE_POPULATED = "notifications-populated.json"; + private static final String FILE_EMPTY = "notifications-empty.json"; + + /** + * Creates a streamable entity from the given file name in test resources. + * + * @param filename The name of the file in the test resources. + * @return An {@link InputStreamEntity} created from the file. + * @throws Exception if the file (resource) was not found. + */ + private InputStreamEntity createEntityFromFile(String filename) throws Exception { + InputStream is = getClass().getClassLoader().getResourceAsStream(filename); + + if (is == null) { + throw new Exception("Failed to find resource: " + filename); + } + + return new InputStreamEntity(is); + } + + /** + * Helper method to create a simple JsonNode with a "tag_name" property. + * @param tagName The value for the "tag_name" property. + * @return A {@link JsonNode} object. + */ + private JsonNode createJsonNodeWithTag(String tagName) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.createObjectNode().put("tag_name", tagName); + } + + @Test + public void test_jsonStreamPopulated() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_POPULATED); + Stream stream = ConnectServiceUtil.toJsonStream(entity); + assertEquals("Expected all 25 elements to be present", 25L, stream.count()); + } + + @Test + public void test_jsonStreamEmpty() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_EMPTY); + Stream stream = ConnectServiceUtil.toJsonStream(entity); + assertEquals("Expected no elements in stream", 0L, stream.count()); + } + + @Test + public void test_getCharsetWhenMissing() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_POPULATED); + Charset charset = ConnectServiceUtil.getCharset(entity); + assertEquals(StandardCharsets.UTF_8.name(), charset.name()); + } + + @Test + public void test_getCharsetWhenSet() throws Exception { + //inspired by https://github.com/apache/httpcomponents-core/blob/4.4.x/httpcore/src/test/java/org/apache/http/entity/TestContentType.java#L173 + BasicHttpEntity entity = new BasicHttpEntity(); + String expectedCharset = "UTF-16"; + entity.setContentType(new BasicHeader("Content-Type", "application/json; charset=" + expectedCharset)); + // Set some dummy content for the entity to be valid, though getCharset only looks at headers + entity.setContent(new ByteArrayInputStream("{}".getBytes(StandardCharsets.UTF_8))); + Charset charset = ConnectServiceUtil.getCharset(entity); + assertEquals(expectedCharset, charset.name()); + } + + @Test + public void test_getCharsetWhenSetButNoCharsetParam() throws Exception { + BasicHttpEntity entity = new BasicHttpEntity(); + entity.setContentType(new BasicHeader("Content-Type", "application/json")); + entity.setContent(new ByteArrayInputStream("{}".getBytes(StandardCharsets.UTF_8))); + Charset charset = ConnectServiceUtil.getCharset(entity); + assertEquals(StandardCharsets.UTF_8.name(), charset.name()); + } + + @Test + public void test_dropOlderThan_currentIsOlderMajorVersion() throws Exception { + Version current = Version.parse("3.12.0"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertTrue("Predicate should be true if current version is older (major)", + predicate.test(createJsonNodeWithTag("4.0.0"))); + } + + @Test + public void test_dropOlderThan_currentIsNewerMajorVersion() throws Exception { + Version current = Version.parse("4.0.0"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertFalse("Predicate should be false if current version is newer (major)", + predicate.test(createJsonNodeWithTag("3.12.0"))); + } + + @Test + public void test_dropOlderThan_currentIsSameVersion() throws Exception { + Version current = Version.parse("4.0.0"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertFalse("Predicate should be false if current version is the same", + predicate.test(createJsonNodeWithTag("4.0.0"))); + } + + @Test + public void test_dropOlderThan_currentIsOlderMinor() throws Exception { + Version current = Version.parse("4.0.1"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertTrue("Predicate should be true if current version is older (minor)", + predicate.test(createJsonNodeWithTag("4.1.1"))); + } + + @Test + public void test_dropOlderThan_currentIsNewerMinor() throws Exception { + Version current = Version.parse("4.1.1"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertFalse("Predicate should be false if current version is newer (minor)", + predicate.test(createJsonNodeWithTag("4.0.1"))); + } + + @Test + public void test_dropOlderThan_currentIsOlderRevision() throws Exception { + Version current = Version.parse("4.0.0"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertTrue("Predicate should be true if current version is older (revision)", + predicate.test(createJsonNodeWithTag("4.0.1"))); + } + + @Test + public void test_dropOlderThan_currentIsNewerRevision() throws Exception { + Version current = Version.parse("4.0.1"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertFalse("Predicate should be false if current version is newer (revision)", + predicate.test(createJsonNodeWithTag("4.0.0"))); + } + + @Test + public void test_dropOlderThan_predicateIsFalseForInvalidOtherVersion() throws Exception { + Version current = Version.parse("4.0.1"); + Predicate predicate = ConnectServiceUtil.dropOlderThan(current); + assertFalse("Predicate should be false if the other version string is invalid", + predicate.test(createJsonNodeWithTag("INVALID_VERSION_STRING"))); + } + + // Tests for notification filtering using dropOlderThan + @Test + public void test_filterNotifications_currentVersionNewerThanAllOther() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_POPULATED); + Version current = Version.parse("4.6.0"); + Stream notifications = ConnectServiceUtil.toJsonStream(entity) + .filter(ConnectServiceUtil.dropOlderThan(current)); + assertEquals("Expected no notifications given a current version newer than all others", 0L, notifications.count()); + } + + @Test + public void test_filterNotifications_emptyComparisonList() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_EMPTY); + Version current = Version.parse("1.0.0"); + Stream notifications = ConnectServiceUtil.toJsonStream(entity) + .filter(ConnectServiceUtil.dropOlderThan(current)); + assertEquals("Expected no notifications given an empty comparison list", 0L, notifications.count()); + } + + @Test + public void test_filterNotifications_matchingLatestVersion() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_POPULATED); + Version current = Version.parse("4.5.2"); + Stream notifications = ConnectServiceUtil.toJsonStream(entity) + .filter(ConnectServiceUtil.dropOlderThan(current)); + assertEquals("Expected no notifications given a current version matching the latest in other list", 0L, notifications.count()); + } + + @Test + public void test_filterNotifications_someVersionsNewer() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_POPULATED); + Version current = Version.parse("4.2.0"); + Stream notifications = ConnectServiceUtil.toJsonStream(entity) + .filter(ConnectServiceUtil.dropOlderThan(current)); + assertEquals("Expected newer versions to generate notifications", 7L, notifications.count()); + } + + @Test + public void test_filterNotifications_allVersionsNewer() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_POPULATED); + Version current = Version.parse("1.0.0"); + Stream notifications = ConnectServiceUtil.toJsonStream(entity) + .filter(ConnectServiceUtil.dropOlderThan(current)); + assertEquals("Expected all versions in populated list to be newer", 25L, notifications.count()); + } + + @Test + public void test_notificationInfo() throws Exception { + HttpEntity entity = createEntityFromFile(FILE_POPULATED); + Optional firstNode = ConnectServiceUtil.toJsonStream(entity).findFirst(); + + assertTrue("A node was expected to act upon", firstNode.isPresent()); + + JsonNode orig = firstNode.get(); + + Notification created = ConnectServiceUtil.toNotification(orig); + assertEquals(orig.get("id").asInt(), (int) created.getId()); + assertEquals(orig.get("name").asText(), created.getName()); + assertEquals(orig.get("published_at").asText(), created.getDate()); + assertEquals(orig.get("body_html").asText(), created.getContent()); + } +} diff --git a/server/test/resources/notifications-empty.json b/server/test/resources/notifications-empty.json new file mode 100644 index 000000000..41b42e677 --- /dev/null +++ b/server/test/resources/notifications-empty.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/server/test/resources/notifications-populated.json b/server/test/resources/notifications-populated.json new file mode 100644 index 000000000..0353d36ad --- /dev/null +++ b/server/test/resources/notifications-populated.json @@ -0,0 +1,1144 @@ +[ + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/176445080", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/176445080/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/176445080/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.5.2", + "id": 176445080, + "author": { + "login": "jdonextgen", + "id": 100001865, + "node_id": "U_kgDOBfXoSQ", + "avatar_url": "https://avatars.githubusercontent.com/u/100001865?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/jdonextgen", + "html_url": "https://github.com/jdonextgen", + "followers_url": "https://api.github.com/users/jdonextgen/followers", + "following_url": "https://api.github.com/users/jdonextgen/following{/other_user}", + "gists_url": "https://api.github.com/users/jdonextgen/gists{/gist_id}", + "starred_url": "https://api.github.com/users/jdonextgen/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/jdonextgen/subscriptions", + "organizations_url": "https://api.github.com/users/jdonextgen/orgs", + "repos_url": "https://api.github.com/users/jdonextgen/repos", + "events_url": "https://api.github.com/users/jdonextgen/events{/privacy}", + "received_events_url": "https://api.github.com/users/jdonextgen/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4KhFaY", + "tag_name": "4.5.2", + "target_commitish": "development", + "name": "Mirth Connect 4.5.2", + "draft": false, + "prerelease": false, + "created_at": "2024-09-10T13:12:21Z", + "published_at": "2024-09-23T16:36:51Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.5.2", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.5.2", + "body_html": "

Mirth® Connect 4.5.2 is a patch release that includes enhancements, bug fixes, and security improvements. For more details, visit our See What's New and Release Notes pages linked below.

\n

NOTICE: In 2025, Mirth® Connect will move to Java 17 as the minimum supported Java version.

\n

See What's New | Upgrade Guide | Release Notes

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/6310" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/167690613", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/167690613/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/167690613/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.5.1", + "id": 167690613, + "author": { + "login": "joaryche", + "id": 17276087, + "node_id": "MDQ6VXNlcjE3Mjc2MDg3", + "avatar_url": "https://avatars.githubusercontent.com/u/17276087?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/joaryche", + "html_url": "https://github.com/joaryche", + "followers_url": "https://api.github.com/users/joaryche/followers", + "following_url": "https://api.github.com/users/joaryche/following{/other_user}", + "gists_url": "https://api.github.com/users/joaryche/gists{/gist_id}", + "starred_url": "https://api.github.com/users/joaryche/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/joaryche/subscriptions", + "organizations_url": "https://api.github.com/users/joaryche/orgs", + "repos_url": "https://api.github.com/users/joaryche/repos", + "events_url": "https://api.github.com/users/joaryche/events{/privacy}", + "received_events_url": "https://api.github.com/users/joaryche/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4J_sF1", + "tag_name": "4.5.1", + "target_commitish": "release/4.5.1", + "name": "Mirth Connect 4.5.1", + "draft": false, + "prerelease": false, + "created_at": "2024-07-19T20:29:36Z", + "published_at": "2024-07-29T16:32:18Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.5.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.5.1", + "body_html": "

Mirth Connect 4.5.1 is a patch release that includes security improvements.

\n

See What's New | Upgrade Guide | Release Notes

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/6269" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/139361411", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/139361411/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/139361411/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.5.0", + "id": 139361411, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4ITnyD", + "tag_name": "4.5.0", + "target_commitish": "development", + "name": "Mirth Connect 4.5.0", + "draft": false, + "prerelease": false, + "created_at": "2024-01-19T21:11:27Z", + "published_at": "2024-01-31T17:07:21Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.5.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.5.0", + "body_html": "

This release is a major release that includes security updates and bug fixes. We have also updated the Duo Multi-Factor Authentication to use the new Universal Prompt because the Traditional Prompt will no longer be accessible after March 30, 2024. For more information about the Duo Multi-Factor Authentication changes, check out the 4.5.0 What's New and Upgrade Guide pages linked below. See the release notes for the list of fixes and updates.

\n

NOTICE (UPDATED): After reviewing community feedback, we have decided that starting in Mirth Connect version 4.7.0 and Mirth Connect Administrator Launcher version 1.5.0, we will be switching our minimum supported Java version from Java 8 to Java 17.

\n

See What's New | Upgrade Guide | Release Notes

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/6080", + "reactions": { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/139361411/reactions", + "total_count": 1, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 1, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/128198598", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/128198598/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/128198598/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.4.2", + "id": 128198598, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4HpCfG", + "tag_name": "4.4.2", + "target_commitish": "development", + "name": "Mirth Connect 4.4.2", + "draft": false, + "prerelease": false, + "created_at": "2023-10-24T19:21:51Z", + "published_at": "2023-11-06T18:27:55Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.4.2", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.4.2", + "body_html": "

Mirth Connect 4.4.2 is a patch release that includes bug fixes and an improvement to exporting messages.

\n

See What's New | Upgrade Guide | Release Notes

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/5977" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/125276770", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/125276770/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/125276770/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.4.1", + "id": 125276770, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4Hd5Ji", + "tag_name": "4.4.1", + "target_commitish": "development", + "name": "Mirth Connect 4.4.1", + "draft": false, + "prerelease": false, + "created_at": "2023-10-10T17:23:22Z", + "published_at": "2023-10-16T17:47:07Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.4.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.4.1", + "body_html": "

Mirth Connect 4.4.1 is a patch release that includes security improvements.

\n

See What's New | Upgrade Guide | Release Notes - Connect | Release Notes - Connect Docker

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/5955" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/114552134", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/114552134/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/114552134/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.4.0", + "id": 114552134, + "author": { + "login": "jdonextgen", + "id": 100001865, + "node_id": "U_kgDOBfXoSQ", + "avatar_url": "https://avatars.githubusercontent.com/u/100001865?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/jdonextgen", + "html_url": "https://github.com/jdonextgen", + "followers_url": "https://api.github.com/users/jdonextgen/followers", + "following_url": "https://api.github.com/users/jdonextgen/following{/other_user}", + "gists_url": "https://api.github.com/users/jdonextgen/gists{/gist_id}", + "starred_url": "https://api.github.com/users/jdonextgen/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/jdonextgen/subscriptions", + "organizations_url": "https://api.github.com/users/jdonextgen/orgs", + "repos_url": "https://api.github.com/users/jdonextgen/repos", + "events_url": "https://api.github.com/users/jdonextgen/events{/privacy}", + "received_events_url": "https://api.github.com/users/jdonextgen/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4G0-1G", + "tag_name": "4.4.0", + "target_commitish": "development", + "name": "Mirth Connect 4.4.0", + "draft": false, + "prerelease": false, + "created_at": "2023-07-20T21:49:05Z", + "published_at": "2023-07-31T19:15:56Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.4.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.4.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 4.4.0 is a major release containing new features like adding new functionality to the Mirth Connect Setup Wizard such as:

\n
    \n
  1. Adding the ability to download and install your Mirth Connect commercial extensions at the time Mirth Connect is installed or upgraded.
  2. \n
  3. When upgrading Mirth Connect, the Setup Wizard now displays the existing values for the Destination Directory, License Key, Network Ports, and Password Requirements from your mirth.properties file rather than the standard default values or the values that were entered previously.
  4. \n
\n

Other new features include improved event log messages and a new server event that fires when the Mirth Connect Server has finished starting up. This release also contains enhancements for the Mirth Connect Administrator Launcher, the Mirth Connect Docker images, and several bug fixes, security improvements, and updates to both Mirth Connect Core and our commercial extensions.

\n

See What's New | Upgrade Guide | Release Notes

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/5864", + "reactions": { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/114552134/reactions", + "total_count": 2, + "+1": 2, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/97204987", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/97204987/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/97204987/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.3.0", + "id": 97204987, + "author": { + "login": "joaryche", + "id": 17276087, + "node_id": "MDQ6VXNlcjE3Mjc2MDg3", + "avatar_url": "https://avatars.githubusercontent.com/u/17276087?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/joaryche", + "html_url": "https://github.com/joaryche", + "followers_url": "https://api.github.com/users/joaryche/followers", + "following_url": "https://api.github.com/users/joaryche/following{/other_user}", + "gists_url": "https://api.github.com/users/joaryche/gists{/gist_id}", + "starred_url": "https://api.github.com/users/joaryche/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/joaryche/subscriptions", + "organizations_url": "https://api.github.com/users/joaryche/orgs", + "repos_url": "https://api.github.com/users/joaryche/repos", + "events_url": "https://api.github.com/users/joaryche/events{/privacy}", + "received_events_url": "https://api.github.com/users/joaryche/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4Fyzr7", + "tag_name": "4.3.0", + "target_commitish": "development", + "name": "Mirth Connect 4.3.0", + "draft": false, + "prerelease": false, + "created_at": "2023-03-09T20:28:09Z", + "published_at": "2023-03-28T16:11:37Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.3.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.3.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208 / CVE-2023-37679. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 4.3.0 is a major release containing new features like adding new functionality to the Mirth Connect Setup Wizard, adding the ability for resource and channel-specific classloaders to load child-first or parent-first, and added a default implementation of the getObjectsForSwaggerExamples() method in the ServicePlugin class. This release also contains enhancements for the Mirth Connect Administrator Launcher, the Mirth Connect Docker images, and several bug fixes and security improvements.

\n

See What's New | Upgrade Guide | Release Notes

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/5736", + "reactions": { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/97204987/reactions", + "total_count": 6, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 4, + "confused": 0, + "heart": 0, + "rocket": 2, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/85343153", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/85343153/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/85343153/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.2.0", + "id": 85343153, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4FFjux", + "tag_name": "4.2.0", + "target_commitish": "development", + "name": "Mirth Connect 4.2.0", + "draft": false, + "prerelease": false, + "created_at": "2022-11-29T22:33:01Z", + "published_at": "2022-12-07T18:43:04Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.2.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.2.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208 / CVE-2023-37679. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 4.2.0 is a major release containing new features like streamlining the process of selecting a listener port, adding the usernames to the overwriting channel changes warning message, adding additional, sortable columns to the Events screen, and being able to select multiple messages when sending messages through a channel. We also added new message integrity features like adding new JavaScript utility methods for hashing channel messages and automatically hashing outgoing messages. This release also contains enhancements for the Mirth Connect Administrator Launcher and several bug fixes, security improvements, and updates to the commercial extensions.

\n

See What's New | Upgrade Guide | Release Notes

", + "reactions": { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/85343153/reactions", + "total_count": 1, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 1, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/76621540", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/76621540/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/76621540/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.1.1", + "id": 76621540, + "author": { + "login": "jdonextgen", + "id": 100001865, + "node_id": "U_kgDOBfXoSQ", + "avatar_url": "https://avatars.githubusercontent.com/u/100001865?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/jdonextgen", + "html_url": "https://github.com/jdonextgen", + "followers_url": "https://api.github.com/users/jdonextgen/followers", + "following_url": "https://api.github.com/users/jdonextgen/following{/other_user}", + "gists_url": "https://api.github.com/users/jdonextgen/gists{/gist_id}", + "starred_url": "https://api.github.com/users/jdonextgen/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/jdonextgen/subscriptions", + "organizations_url": "https://api.github.com/users/jdonextgen/orgs", + "repos_url": "https://api.github.com/users/jdonextgen/repos", + "events_url": "https://api.github.com/users/jdonextgen/events{/privacy}", + "received_events_url": "https://api.github.com/users/jdonextgen/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4EkSbk", + "tag_name": "4.1.1", + "target_commitish": "development", + "name": "Mirth Connect 4.1.1", + "draft": false, + "prerelease": false, + "created_at": "2022-08-24T17:30:08Z", + "published_at": "2022-09-08T17:23:43Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.1.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.1.1", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208 / CVE-2023-37679. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 4.1.1 is a patch release containing modifications to the Welcome to Mirth Connect screen and two fixed defects.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/73197971", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/73197971/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/73197971/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.1.0", + "id": 73197971, + "author": { + "login": "lmillergithub", + "id": 99997555, + "node_id": "U_kgDOBfXXcw", + "avatar_url": "https://avatars.githubusercontent.com/u/99997555?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/lmillergithub", + "html_url": "https://github.com/lmillergithub", + "followers_url": "https://api.github.com/users/lmillergithub/followers", + "following_url": "https://api.github.com/users/lmillergithub/following{/other_user}", + "gists_url": "https://api.github.com/users/lmillergithub/gists{/gist_id}", + "starred_url": "https://api.github.com/users/lmillergithub/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lmillergithub/subscriptions", + "organizations_url": "https://api.github.com/users/lmillergithub/orgs", + "repos_url": "https://api.github.com/users/lmillergithub/repos", + "events_url": "https://api.github.com/users/lmillergithub/events{/privacy}", + "received_events_url": "https://api.github.com/users/lmillergithub/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4EXOmT", + "tag_name": "4.1.0", + "target_commitish": "development", + "name": "Mirth Connect 4.1.0", + "draft": false, + "prerelease": false, + "created_at": "2022-07-29T18:08:28Z", + "published_at": "2022-07-29T18:47:37Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.1.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.1.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208 / CVE-2023-37679. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 4.1.0 includes new features such as new event log messages, additional fields to the Welcome to Mirth Connect screen, new information included in alerts as well as many smaller changes, updates, and improvements. This release also contains several improvements to commercial extensions.

\n

See What's New | Upgrade Guide | Release Notes

", + "reactions": { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/73197971/reactions", + "total_count": 2, + "+1": 1, + "-1": 0, + "laugh": 0, + "hooray": 1, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/65374146", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/65374146/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/65374146/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.0.1", + "id": 65374146, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4D5YfC", + "tag_name": "4.0.1", + "target_commitish": "development", + "name": "Mirth Connect 4.0.1", + "draft": false, + "prerelease": false, + "created_at": "2022-04-21T22:34:35Z", + "published_at": "2022-04-26T16:28:38Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.0.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.0.1", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208 / CVE-2023-37679. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 4.0.1 is a patch release containing a bug fix which includes fixing a Jetty keystore regression that caused Connect servers using a PKCS12 keystore containing a wildcard certificate and/or a certificate with a SAN to throw an exception on startup.

\n

See What's New | Upgrade Guide | Release Notes

", + "discussion_url": "https://github.com/nextgenhealthcare/connect/discussions/5158", + "reactions": { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/65374146/reactions", + "total_count": 2, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 2, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/63072651", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/63072651/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/63072651/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/4.0.0", + "id": 63072651, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "RE_kwDOCCE7Tc4DwmmL", + "tag_name": "4.0.0", + "target_commitish": "development", + "name": "Mirth Connect 4.0.0", + "draft": false, + "prerelease": false, + "created_at": "2022-03-21T14:59:08Z", + "published_at": "2022-03-29T18:56:57Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/4.0.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/4.0.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208 / CVE-2023-37679. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 4.0.0 includes new features such as a JavaScript Debugger, Login Notice and Consent dialog with options, Inactivity Logout with options, as well as many smaller changes, updates, and improvements. This release also contains several improvements to commercial extensions.

\n

See What's New | Upgrade Guide | Release Notes

", + "reactions": { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/63072651/reactions", + "total_count": 3, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 3, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/51058683", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/51058683/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/51058683/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.12.0", + "id": 51058683, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTUxMDU4Njgz", + "tag_name": "3.12.0", + "target_commitish": "development", + "name": "Mirth Connect 3.12.0", + "draft": false, + "prerelease": false, + "created_at": "2021-09-02T16:52:39Z", + "published_at": "2021-10-08T20:13:04Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.12.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.12.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

Mirth Connect 3.12.0 is a minor release that includes database performance improvements, improves visual HL7 representation, message pruning, keystore handling, PDF generation, community contributions, and fixes several security vulnerabilities. It also contains many improvements to commercial extensions.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/42025125", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/42025125/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/42025125/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.11.0", + "id": 42025125, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQyMDI1MTI1", + "tag_name": "3.11.0", + "target_commitish": "development", + "name": "NextGen Connect 3.11.0", + "draft": false, + "prerelease": false, + "created_at": "2021-04-06T17:50:04Z", + "published_at": "2021-04-26T18:09:24Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.11.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.11.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.11.0 is a minor release that includes improvements to licensing and the NCPDP data type. It also includes various security fixes, general bug fixes, and improvements to commercial extensions.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/36406968", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/36406968/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/36406968/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.10.1", + "id": 36406968, + "author": { + "login": "cturczynskyj", + "id": 15792647, + "node_id": "MDQ6VXNlcjE1NzkyNjQ3", + "avatar_url": "https://avatars.githubusercontent.com/u/15792647?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/cturczynskyj", + "html_url": "https://github.com/cturczynskyj", + "followers_url": "https://api.github.com/users/cturczynskyj/followers", + "following_url": "https://api.github.com/users/cturczynskyj/following{/other_user}", + "gists_url": "https://api.github.com/users/cturczynskyj/gists{/gist_id}", + "starred_url": "https://api.github.com/users/cturczynskyj/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/cturczynskyj/subscriptions", + "organizations_url": "https://api.github.com/users/cturczynskyj/orgs", + "repos_url": "https://api.github.com/users/cturczynskyj/repos", + "events_url": "https://api.github.com/users/cturczynskyj/events{/privacy}", + "received_events_url": "https://api.github.com/users/cturczynskyj/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM2NDA2OTY4", + "tag_name": "3.10.1", + "target_commitish": "release/3.10.1", + "name": "NextGen Connect 3.10.1", + "draft": false, + "prerelease": false, + "created_at": "2021-01-05T22:05:20Z", + "published_at": "2021-01-14T18:54:27Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.10.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.10.1", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.10.1 is a patch release containing a few bug fixes including fixing a velocity replacement regression that caused velocity variables with hyphens to stop working properly and fixed an issue where installing extensions using the Connect Administrator would fail.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/33934269", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/33934269/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/33934269/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.10.0", + "id": 33934269, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTMzOTM0MjY5", + "tag_name": "3.10.0", + "target_commitish": "development", + "name": "NextGen Connect 3.10.0", + "draft": false, + "prerelease": false, + "created_at": "2020-11-05T21:49:02Z", + "published_at": "2020-11-13T18:51:00Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.10.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.10.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.10 includes better SQL Server database support, security improvements through fixes and library updates, and improvements for the Advanced Clustering plugin with a focus on improving performance of many of the tasks that are carried out on a frequent interval.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/29829664", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/29829664/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/29829664/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.9.1", + "id": 29829664, + "author": { + "login": "pladesma", + "id": 4097281, + "node_id": "MDQ6VXNlcjQwOTcyODE=", + "avatar_url": "https://avatars.githubusercontent.com/u/4097281?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pladesma", + "html_url": "https://github.com/pladesma", + "followers_url": "https://api.github.com/users/pladesma/followers", + "following_url": "https://api.github.com/users/pladesma/following{/other_user}", + "gists_url": "https://api.github.com/users/pladesma/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pladesma/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pladesma/subscriptions", + "organizations_url": "https://api.github.com/users/pladesma/orgs", + "repos_url": "https://api.github.com/users/pladesma/repos", + "events_url": "https://api.github.com/users/pladesma/events{/privacy}", + "received_events_url": "https://api.github.com/users/pladesma/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI5ODI5NjY0", + "tag_name": "3.9.1", + "target_commitish": "release/3.9.1", + "name": "NextGen Connect 3.9.1", + "draft": false, + "prerelease": false, + "created_at": "2020-07-21T22:12:12Z", + "published_at": "2020-08-18T17:57:28Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.9.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.9.1", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.9.1 is a patch release containing a few bug fixes including plugging memory leaks for SMB and SFTP file readers as well as adding support for eHealth Exchange UDDI providers in the Interoperability plugin.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/25582093", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/25582093/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/25582093/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.9.0", + "id": 25582093, + "author": { + "login": "cturczynskyj", + "id": 15792647, + "node_id": "MDQ6VXNlcjE1NzkyNjQ3", + "avatar_url": "https://avatars.githubusercontent.com/u/15792647?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/cturczynskyj", + "html_url": "https://github.com/cturczynskyj", + "followers_url": "https://api.github.com/users/cturczynskyj/followers", + "following_url": "https://api.github.com/users/cturczynskyj/following{/other_user}", + "gists_url": "https://api.github.com/users/cturczynskyj/gists{/gist_id}", + "starred_url": "https://api.github.com/users/cturczynskyj/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/cturczynskyj/subscriptions", + "organizations_url": "https://api.github.com/users/cturczynskyj/orgs", + "repos_url": "https://api.github.com/users/cturczynskyj/repos", + "events_url": "https://api.github.com/users/cturczynskyj/events{/privacy}", + "received_events_url": "https://api.github.com/users/cturczynskyj/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI1NTgyMDkz", + "tag_name": "3.9.0", + "target_commitish": "development", + "name": "NextGen Connect 3.9.0", + "draft": false, + "prerelease": false, + "created_at": "2020-04-03T17:46:14Z", + "published_at": "2020-04-16T17:41:26Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.9.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.9.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.9.0 introduces dozens of new features, improvements, and bug fixes!

\n

Some key features and benefits of the new release include:

\n
    \n
  • \n

    JSON Support in REST API — Updated, easier to use REST API documentation, and JSON support now too!

    \n
  • \n
  • \n

    SMB v2/v3 Support — SMB versions 2.0.2 through 3.1.1 are now supported on our File Reader/Writer connectors!

    \n
  • \n
  • \n

    TCP Sender Server Mode — Similar to how the TCP Listener has client/server modes, the TCP Sender now does too. When the TCP Sender is in server mode, Messages will queue until at least one client connects, and when a message gets sent it will be sent to all currently connected clients.

    \n
  • \n
  • \n

    FHIR R4/R5 Support — For those of you that don't know, our FHIR Connector Extension is freely available, and now supports the latest versions R4 and R5 (Preview 1). It also supports other older versions as well. Go to our website to download it!

    \n
  • \n
  • \n

    Channel History UI Improvements — Our Channel History extension has been updated with performance improvements for very large channels/scripts. We also now have the ability to switch between Unified vs Side-by-side diffs, and Previous/Next buttons to cycle through changes.

    \n
  • \n
  • \n

    And More!

    \n
  • \n
\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/20452127", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/20452127/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/20452127/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.8.1", + "id": 20452127, + "author": { + "login": "narupley", + "id": 3595934, + "node_id": "MDQ6VXNlcjM1OTU5MzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/3595934?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/narupley", + "html_url": "https://github.com/narupley", + "followers_url": "https://api.github.com/users/narupley/followers", + "following_url": "https://api.github.com/users/narupley/following{/other_user}", + "gists_url": "https://api.github.com/users/narupley/gists{/gist_id}", + "starred_url": "https://api.github.com/users/narupley/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/narupley/subscriptions", + "organizations_url": "https://api.github.com/users/narupley/orgs", + "repos_url": "https://api.github.com/users/narupley/repos", + "events_url": "https://api.github.com/users/narupley/events{/privacy}", + "received_events_url": "https://api.github.com/users/narupley/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTIwNDUyMTI3", + "tag_name": "3.8.1", + "target_commitish": "development", + "name": "NextGen Connect 3.8.1", + "draft": false, + "prerelease": false, + "created_at": "2019-10-03T14:42:53Z", + "published_at": "2019-10-03T16:57:18Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.8.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.8.1", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.8.1 is a small patch release including a couple of enhancements / bug fixes for the Interoperability Connector Suite (IHE protocols) extension.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/18069858", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/18069858/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/18069858/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.8.0", + "id": 18069858, + "author": { + "login": "narupley", + "id": 3595934, + "node_id": "MDQ6VXNlcjM1OTU5MzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/3595934?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/narupley", + "html_url": "https://github.com/narupley", + "followers_url": "https://api.github.com/users/narupley/followers", + "following_url": "https://api.github.com/users/narupley/following{/other_user}", + "gists_url": "https://api.github.com/users/narupley/gists{/gist_id}", + "starred_url": "https://api.github.com/users/narupley/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/narupley/subscriptions", + "organizations_url": "https://api.github.com/users/narupley/orgs", + "repos_url": "https://api.github.com/users/narupley/repos", + "events_url": "https://api.github.com/users/narupley/events{/privacy}", + "received_events_url": "https://api.github.com/users/narupley/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTE4MDY5ODU4", + "tag_name": "3.8.0", + "target_commitish": "development", + "name": "NextGen Connect 3.8.0", + "draft": false, + "prerelease": false, + "created_at": "2019-06-05T16:36:51Z", + "published_at": "2019-06-18T16:51:31Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.8.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.8.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.8.0 is a minor stability update with a couple dozen bug fixes, some third-party library updates, and a few new features and improvements.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/16415449", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/16415449/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/16415449/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.7.1", + "id": 16415449, + "author": { + "login": "narupley", + "id": 3595934, + "node_id": "MDQ6VXNlcjM1OTU5MzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/3595934?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/narupley", + "html_url": "https://github.com/narupley", + "followers_url": "https://api.github.com/users/narupley/followers", + "following_url": "https://api.github.com/users/narupley/following{/other_user}", + "gists_url": "https://api.github.com/users/narupley/gists{/gist_id}", + "starred_url": "https://api.github.com/users/narupley/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/narupley/subscriptions", + "organizations_url": "https://api.github.com/users/narupley/orgs", + "repos_url": "https://api.github.com/users/narupley/repos", + "events_url": "https://api.github.com/users/narupley/events{/privacy}", + "received_events_url": "https://api.github.com/users/narupley/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTE2NDE1NDQ5", + "tag_name": "3.7.1", + "target_commitish": "development", + "name": "NextGen Connect 3.7.1", + "draft": false, + "prerelease": false, + "created_at": "2019-03-28T15:56:01Z", + "published_at": "2019-03-28T16:36:16Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.7.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.7.1", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.7.1 is a patch release containing around a dozen bug fixes.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/14627249", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/14627249/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/14627249/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.7.0", + "id": 14627249, + "author": { + "login": "narupley", + "id": 3595934, + "node_id": "MDQ6VXNlcjM1OTU5MzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/3595934?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/narupley", + "html_url": "https://github.com/narupley", + "followers_url": "https://api.github.com/users/narupley/followers", + "following_url": "https://api.github.com/users/narupley/following{/other_user}", + "gists_url": "https://api.github.com/users/narupley/gists{/gist_id}", + "starred_url": "https://api.github.com/users/narupley/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/narupley/subscriptions", + "organizations_url": "https://api.github.com/users/narupley/orgs", + "repos_url": "https://api.github.com/users/narupley/repos", + "events_url": "https://api.github.com/users/narupley/events{/privacy}", + "received_events_url": "https://api.github.com/users/narupley/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTE0NjI3MjQ5", + "tag_name": "3.7.0", + "target_commitish": "development", + "name": "NextGen Connect 3.7.0", + "draft": false, + "prerelease": false, + "created_at": "2018-12-19T22:05:43Z", + "published_at": "2018-12-19T22:59:30Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.7.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.7.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.7.0 includes dozens of new features, improvements, and bug fixes!

\n

Some key features and benefits of the new release include:

\n
    \n
  • \n

    Java 11 Support — Java 11 is the newest \"major\" release of Java, and with it comes lots of great features like TLS 1.3 support. It's also the latest LTS release for Oracle support customers. Java 8 is not yet EOL so it can still definitely be used.

    \n
  • \n
  • \n

    OpenJDK Support — No need to be worried about Oracle's recent license changes. With 3.7, Connect now supports both the official Oracle JDK, as well as OpenJDK distributions like the Oracle OpenJDK JDK, Azul Zulu, AdoptOpenJDK, and others! So when public security updates cease for Oracle JDK 8, you won't be forced to purchase Oracle support. You can choose whatever Java distribution you want.

    \n
  • \n
  • \n

    Database Connection Pool Options — The database connections Connect uses can now be separated into read/write and read-only pools, which means you can leverage read-replica database scaling for running Connect in a cluster.

    \n
  • \n
  • \n

    Advanced Clustering: Guaranteed Message Order — Our Advanced Clustering extension is great for horizontally scaling your Connect servers, and paired with a load balancer you can greatly improve throughput by allowing channels to run on multiple servers simultaneously. However in some cases you want messages for a particular channel to process in order. This is now possible in 3.7, and can be enabled on a per-channel and per-destination-queue basis!

    \n
  • \n
  • \n

    User Authorization: Channel Tags / Groups — The role/privilege options for our User Authorization extension have been expanded in 3.7! With this you can create more fine-tuned roles. For example you can decide that a particular user should only be able to View/Manage channels that have a certain tag, or that belong to a certain group.

    \n
  • \n
  • \n

    And More!

    \n
  • \n
\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/14627161", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/14627161/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/14627161/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.6.2", + "id": 14627161, + "author": { + "login": "narupley", + "id": 3595934, + "node_id": "MDQ6VXNlcjM1OTU5MzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/3595934?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/narupley", + "html_url": "https://github.com/narupley", + "followers_url": "https://api.github.com/users/narupley/followers", + "following_url": "https://api.github.com/users/narupley/following{/other_user}", + "gists_url": "https://api.github.com/users/narupley/gists{/gist_id}", + "starred_url": "https://api.github.com/users/narupley/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/narupley/subscriptions", + "organizations_url": "https://api.github.com/users/narupley/orgs", + "repos_url": "https://api.github.com/users/narupley/repos", + "events_url": "https://api.github.com/users/narupley/events{/privacy}", + "received_events_url": "https://api.github.com/users/narupley/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTE0NjI3MTYx", + "tag_name": "3.6.2", + "target_commitish": "development", + "name": "NextGen Connect 3.6.2", + "draft": false, + "prerelease": false, + "created_at": "2018-12-19T18:45:38Z", + "published_at": "2018-12-19T22:53:14Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.6.2", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.6.2", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.6.2 is a patch release containing a few bug fixes.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/12060838", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/12060838/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/12060838/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.6.1", + "id": 12060838, + "author": { + "login": "narupley", + "id": 3595934, + "node_id": "MDQ6VXNlcjM1OTU5MzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/3595934?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/narupley", + "html_url": "https://github.com/narupley", + "followers_url": "https://api.github.com/users/narupley/followers", + "following_url": "https://api.github.com/users/narupley/following{/other_user}", + "gists_url": "https://api.github.com/users/narupley/gists{/gist_id}", + "starred_url": "https://api.github.com/users/narupley/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/narupley/subscriptions", + "organizations_url": "https://api.github.com/users/narupley/orgs", + "repos_url": "https://api.github.com/users/narupley/repos", + "events_url": "https://api.github.com/users/narupley/events{/privacy}", + "received_events_url": "https://api.github.com/users/narupley/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTEyMDYwODM4", + "tag_name": "3.6.1", + "target_commitish": "development", + "name": "NextGen Connect 3.6.1", + "draft": false, + "prerelease": false, + "created_at": "2018-07-23T16:35:55Z", + "published_at": "2018-07-23T17:47:08Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.6.1", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.6.1", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.6.1 is a patch release containing a few bug fixes.

\n

See What's New | Upgrade Guide | Release Notes

" + }, + { + "url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/11374428", + "assets_url": "https://api.github.com/repos/nextgenhealthcare/connect/releases/11374428/assets", + "upload_url": "https://uploads.github.com/repos/nextgenhealthcare/connect/releases/11374428/assets{?name,label}", + "html_url": "https://github.com/nextgenhealthcare/connect/releases/tag/3.6.0", + "id": 11374428, + "author": { + "login": "narupley", + "id": 3595934, + "node_id": "MDQ6VXNlcjM1OTU5MzQ=", + "avatar_url": "https://avatars.githubusercontent.com/u/3595934?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/narupley", + "html_url": "https://github.com/narupley", + "followers_url": "https://api.github.com/users/narupley/followers", + "following_url": "https://api.github.com/users/narupley/following{/other_user}", + "gists_url": "https://api.github.com/users/narupley/gists{/gist_id}", + "starred_url": "https://api.github.com/users/narupley/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/narupley/subscriptions", + "organizations_url": "https://api.github.com/users/narupley/orgs", + "repos_url": "https://api.github.com/users/narupley/repos", + "events_url": "https://api.github.com/users/narupley/events{/privacy}", + "received_events_url": "https://api.github.com/users/narupley/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTExMzc0NDI4", + "tag_name": "3.6.0", + "target_commitish": "development", + "name": "NextGen Connect 3.6.0", + "draft": false, + "prerelease": false, + "created_at": "2018-06-06T19:48:59Z", + "published_at": "2018-06-07T16:15:09Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/nextgenhealthcare/connect/tarball/3.6.0", + "zipball_url": "https://api.github.com/repos/nextgenhealthcare/connect/zipball/3.6.0", + "body_html": "

NOTE: This version is affected by the critical vulnerability CVE-2023-43208. You should upgrade to version 4.4.1 or later.

\n
\n

NextGen Connect 3.6.0 includes dozens of new features, improvements, and bug fixes, as well as some new extensions!

\n

Some key features and benefits of the new release include:

\n
    \n
  • \n

    FHIR Connector Extension — In addition to updating our FHIR extension to support STU3 (R3), we've added a number of other enhancements as well! There's a new FHIR Sender destination you can use to connect to external FHIR servers. A new FHIR data type supports both XML and JSON resources simultaneously. A new graphical UI builder for resources is available on the FHIR Sender, as well as on a new transformer step type and code template type. An updated user guide and lots of examples (for instance, how to convert HL7 v2.x to FHIR) are available on the public wiki!

    \n
  • \n
  • \n

    Interoperability Connector Suite — This is a completely new commercial extension that provides Listener and Sender connectors that can help kickstart your eHealth Exchange / Sequoia onboarding and integration. The connectors support the most common operations for PIX, PDQ, XDS.b, XCA, and XCPD. They also support automatic generation and validation of NHIN-compliant SAML/WS-Security sections. In addition, the suite provides a new resource that automatically downloads and syncs business endpoint information from a UDDI Provider!

    \n
  • \n
  • \n

    Multi-Factor Authentication — This commercial extension is new as of 3.5.2, and provides an extra security layer for all user accounts! A secondary device such as a phone, tablet, or landline is used to ensure that no one but the actual user can login, even if they know the correct username and password. Both Duo and generic apps such as Google Authenticator / Authy are supported. When using Duo, advanced options such as lockout protection, automatic enrollment, and policy management are available in the Duo administrator dashboard.

    \n
  • \n
  • \n

    Advanced Clustering Enhancements — View and manage alerts, server logs, connection logs, and global maps across the entire cluster! Automatically prune old, offline server IDs. Global Scripts now auto-compile across the entire cluster. Reload Resources now executes across the entire cluster. More information on our Advanced Clustering commercial extension here!

    \n
  • \n
  • \n

    Amazon S3 support for File Reader/Writer — Both the File Reader and File Writer now support Amazon S3! Set explicit AWS credentials, or use the Default Credential Provider Chain to automatically lookup credentials from a variety of common locations. Temporary credentials are supported as well via the Amazon Security Token Service (STS). You can also supply custom headers for PUT requests, including encryption settings and custom object metadata!

    \n
  • \n
  • \n

    And More!

    \n
  • \n
\n

See What's New | Upgrade Guide | Release Notes

" + } +] From 96934fcce7864fc8e1e8324e7630b3c9509adb40 Mon Sep 17 00:00:00 2001 From: kayyagari Date: Wed, 4 Jun 2025 08:13:50 +0530 Subject: [PATCH 08/10] Changed the mediaRoot to the relative path --- tools/install4j/oie-installer-config.install4j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j index e897b57a3..217a717fa 100644 --- a/tools/install4j/oie-installer-config.install4j +++ b/tools/install4j/oie-installer-config.install4j @@ -3,7 +3,7 @@ - + From 8fb0b06f9a6aa793a7ba2af6da8e068298260cea Mon Sep 17 00:00:00 2001 From: Mitch Gaffigan Date: Sun, 1 Jun 2025 23:50:00 -0500 Subject: [PATCH 09/10] Allow telemetry options to be enabled/disabled via BrandingConstants Adds the following settings to BrandingConstants in client-core: - CENTRAL_USER_REGISTRATION - When false, disables the sending of user demographic information and hides the registration and marketing consent boxes from the first time login screen. - MANDATORY_USER_REGISTRATION - used in conjunction with CENTRAL_USER_REGISTRATION. When this is setting is true and the user id is 1, then the user will not be able to unselect the registration checkbox. - CHECK_FOR_NOTIFICATIONS - When false, allows for notification fetching from the client to be disabled. The notification menu task is also removed. - SEND_USAGE_STATISTICS - When false, allows for sending of usage statistics to be disabled. Also hides the setting which allows users to opt-in or opt-out of sending statistics. With the restoration of the registration checkbox when the appropriate settings are enabled, the adjustment of which fields are required on the user profile has also been restored. Co-authored-by: Tony Germano Signed-off-by: Mitch Gaffigan Signed-off-by: Tony Germano Issue: https://github.com/OpenIntegrationEngine/engine/issues/5 --- .../connect/client/ui/FirstLoginDialog.java | 21 +++++++++++------- .../com/mirth/connect/client/ui/Frame.java | 20 ++++++++++++++++- .../mirth/connect/client/ui/LoginPanel.java | 5 ++++- .../client/ui/SettingsPanelServer.java | 14 ++++++++---- .../client/core/BrandingConstants.java | 8 +++++++ .../client/core/ConnectServiceUtil.java | 22 +++++++++++++++++-- .../src/com/mirth/connect/server/Mirth.java | 6 +++-- 7 files changed, 78 insertions(+), 18 deletions(-) diff --git a/client/src/com/mirth/connect/client/ui/FirstLoginDialog.java b/client/src/com/mirth/connect/client/ui/FirstLoginDialog.java index fbfa5e90d..8d340c0bf 100644 --- a/client/src/com/mirth/connect/client/ui/FirstLoginDialog.java +++ b/client/src/com/mirth/connect/client/ui/FirstLoginDialog.java @@ -9,6 +9,9 @@ package com.mirth.connect.client.ui; +import static com.mirth.connect.client.core.BrandingConstants.CENTRAL_USER_REGISTRATION; +import static com.mirth.connect.client.core.BrandingConstants.MANDATORY_USER_REGISTRATION; + import java.awt.Desktop; import java.awt.Dimension; import java.awt.Point; @@ -47,10 +50,14 @@ public FirstLoginDialog(User currentUser) { finishButton.setEnabled(false); userEditPanel.setUser(this, currentUser); - userEditPanel.setRequiredFields(false, true); - if (currentUser.getId() == 1) { - registerCheckBox.setVisible(false); - } + + final boolean isRegistrationMandatory = CENTRAL_USER_REGISTRATION && MANDATORY_USER_REGISTRATION && currentUser.getId() == 1; + registerCheckBox.setSelected(isRegistrationMandatory); + registerCheckBox.setEnabled(!isRegistrationMandatory); + registerCheckBox.setVisible(CENTRAL_USER_REGISTRATION); + registerCheckBoxActionPerformed(null); + userConsentCheckBox.setVisible(CENTRAL_USER_REGISTRATION); + contentTextPane.setVisible(CENTRAL_USER_REGISTRATION); jLabel2.setForeground(UIConstants.HEADER_TITLE_TEXT_COLOR); setModal(true); @@ -151,7 +158,6 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jScrollPane1.setViewportView(jTextPane1); registerCheckBox.setBackground(new java.awt.Color(255, 255, 255)); - registerCheckBox.setSelected(true); registerCheckBox.setText(String.format("Register user with %s", BrandingConstants.COMPANY_NAME)); registerCheckBox.setToolTipText(String.format("Register your user information with %s to help us
improve the product and provide better service.", BrandingConstants.COMPANY_NAME)); registerCheckBox.addActionListener(new java.awt.event.ActionListener() { @@ -161,7 +167,6 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { }); userConsentCheckBox.setBackground(new java.awt.Color(255, 255, 255)); - userConsentCheckBox.setSelected(true); userConsentCheckBox.setText(String.format("I consent to receive email updates and marketing messages from %s.", BrandingConstants.COMPANY_NAME)); userConsentCheckBox.setToolTipText(""); @@ -273,7 +278,7 @@ private void finishButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN- return; } - if (registerCheckBox.isSelected()) { + if (registerCheckBox.isSelected() && CENTRAL_USER_REGISTRATION) { parent.registerUser(user); } @@ -316,7 +321,7 @@ private void registerCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {// userConsentCheckBox.setSelected(false); userConsentCheckBox.setEnabled(false); } - userEditPanel.setRequiredFields(false, true); + userEditPanel.setRequiredFields(allRequired, true); }//GEN-LAST:event_registerCheckBoxActionPerformed public boolean getResult() { diff --git a/client/src/com/mirth/connect/client/ui/Frame.java b/client/src/com/mirth/connect/client/ui/Frame.java index 717803561..ea33bcfda 100644 --- a/client/src/com/mirth/connect/client/ui/Frame.java +++ b/client/src/com/mirth/connect/client/ui/Frame.java @@ -9,6 +9,10 @@ package com.mirth.connect.client.ui; +import static com.mirth.connect.client.core.BrandingConstants.CENTRAL_USER_REGISTRATION; +import static com.mirth.connect.client.core.BrandingConstants.CHECK_FOR_NOTIFICATIONS; +import static com.mirth.connect.client.core.BrandingConstants.SEND_USAGE_STATISTICS; + import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Color; @@ -1250,7 +1254,9 @@ private void createOtherPane() { otherPane.setTitle("Other"); otherPane.setName(TaskConstants.OTHER_KEY); otherPane.setFocusable(false); - addTask(TaskConstants.OTHER_NOTIFICATIONS, UIConstants.VIEW_NOTIFICATIONS, String.format("View notifications from %s.", BrandingConstants.PRODUCT_NAME), "", new ImageIcon(com.mirth.connect.client.ui.Frame.class.getResource("images/flag_orange.png")), otherPane, null); + if (CHECK_FOR_NOTIFICATIONS) { + addTask(TaskConstants.OTHER_NOTIFICATIONS, UIConstants.VIEW_NOTIFICATIONS, String.format("View notifications from %s.", BrandingConstants.PRODUCT_NAME), "", new ImageIcon(com.mirth.connect.client.ui.Frame.class.getResource("images/flag_orange.png")), otherPane, null); + } addTask(TaskConstants.OTHER_VIEW_USER_API, "View User API", String.format("View documentation for the %s User API.", BrandingConstants.PRODUCT_NAME), "", new ImageIcon(com.mirth.connect.client.ui.Frame.class.getResource("images/page_white_text.png")), otherPane, null); addTask(TaskConstants.OTHER_VIEW_CLIENT_API, "View Client API", String.format("View documentation for the %s Client API.", BrandingConstants.PRODUCT_NAME), "", new ImageIcon(com.mirth.connect.client.ui.Frame.class.getResource("images/page_white_text.png")), otherPane, null); addTask(TaskConstants.OTHER_HELP, "Help", String.format("View help for %s.", BrandingConstants.PRODUCT_NAME), "", new ImageIcon(com.mirth.connect.client.ui.Frame.class.getResource("images/help.png")), otherPane, null); @@ -1268,6 +1274,10 @@ public JXTaskPane getOtherPane() { } public void updateNotificationTaskName(int notifications) { + if (!CHECK_FOR_NOTIFICATIONS) { + return; + } + String taskName = UIConstants.VIEW_NOTIFICATIONS; if (notifications > 0) { taskName += " (" + notifications + ")"; @@ -1949,6 +1959,10 @@ public User getCurrentUser(Component parentComponent, boolean alertOnFailure) { } public void registerUser(final User user) { + if (!CENTRAL_USER_REGISTRATION) { + return; + } + final String workingId = startWorking("Registering user..."); SwingWorker worker = new SwingWorker() { @@ -1972,6 +1986,10 @@ public void done() { } public void sendUsageStatistics() { + if (!SEND_USAGE_STATISTICS) { + return; + } + UpdateSettings updateSettings = null; try { updateSettings = mirthClient.getUpdateSettings(); diff --git a/client/src/com/mirth/connect/client/ui/LoginPanel.java b/client/src/com/mirth/connect/client/ui/LoginPanel.java index d1c6bfef7..5a78f8614 100644 --- a/client/src/com/mirth/connect/client/ui/LoginPanel.java +++ b/client/src/com/mirth/connect/client/ui/LoginPanel.java @@ -9,6 +9,8 @@ package com.mirth.connect.client.ui; +import static com.mirth.connect.client.core.BrandingConstants.CHECK_FOR_NOTIFICATIONS; + import java.awt.Color; import java.awt.Cursor; import java.util.Collections; @@ -609,7 +611,8 @@ private boolean handleSuccess(LoginStatus loginStatus) throws ClientException { // Check for new notifications from update server if enabled String checkForNotifications = userPreferences.getProperty("checkForNotifications"); - if (checkForNotifications == null || BooleanUtils.toBoolean(checkForNotifications)) { + if (CHECK_FOR_NOTIFICATIONS + && (checkForNotifications == null || BooleanUtils.toBoolean(checkForNotifications))) { Set archivedNotifications = new HashSet(); String archivedNotificationString = userPreferences.getProperty("archivedNotifications"); if (archivedNotificationString != null) { diff --git a/client/src/com/mirth/connect/client/ui/SettingsPanelServer.java b/client/src/com/mirth/connect/client/ui/SettingsPanelServer.java index c277a3d60..bd1d523a7 100644 --- a/client/src/com/mirth/connect/client/ui/SettingsPanelServer.java +++ b/client/src/com/mirth/connect/client/ui/SettingsPanelServer.java @@ -9,6 +9,8 @@ package com.mirth.connect.client.ui; +import static com.mirth.connect.client.core.BrandingConstants.SEND_USAGE_STATISTICS; + import java.awt.Color; import java.awt.Cursor; import java.awt.Font; @@ -81,8 +83,12 @@ public SettingsPanelServer(String tabName) { addTask(TaskConstants.SETTINGS_SERVER_RESTORE, "Restore Config", "Restore your server configuration from a server configuration XML file. This will remove and restore your channels, alerts, code templates, server properties, global scripts, and plugin properties.", "", new ImageIcon(com.mirth.connect.client.ui.Frame.class.getResource("images/report_go.png"))); addTask(TaskConstants.SETTINGS_CLEAR_ALL_STATS, "Clear All Statistics", "Reset the current and lifetime statistics for all channels.", "", new ImageIcon(com.mirth.connect.client.ui.Frame.class.getResource("images/chart_bar_delete.png"))); - provideUsageStatsMoreInfoLabel.setToolTipText(BrandingConstants.PRIVACY_TOOLTIP); - provideUsageStatsMoreInfoLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + if (!SEND_USAGE_STATISTICS) { + provideUsageStatsLabel.setVisible(false); + provideUsageStatsYesRadio.setVisible(false); + provideUsageStatsNoRadio.setVisible((false)); + provideUsageStatsMoreInfoLabel.setVisible(false); + } queueBufferSizeField.setDocument(new MirthFieldConstraints(8, false, false, true)); smtpTimeoutField.setDocument(new MirthFieldConstraints(0, false, false, false)); administratorAutoLogoutIntervalField.setDocument(new MirthFieldConstraints(2, false, false, true)); @@ -728,8 +734,8 @@ public void actionPerformed(ActionEvent evt) { provideUsageStatsButtonGroup.add(provideUsageStatsNoRadio); provideUsageStatsMoreInfoLabel = new JLabel("More Info"); - provideUsageStatsMoreInfoLabel.setEnabled(false); - provideUsageStatsMoreInfoLabel.setVisible(false); + provideUsageStatsMoreInfoLabel.setToolTipText(BrandingConstants.PRIVACY_TOOLTIP); + provideUsageStatsMoreInfoLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); provideUsageStatsMoreInfoLabel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { provideUsageStatsMoreInfoLabelMouseClicked(evt); diff --git a/server/src/com/mirth/connect/client/core/BrandingConstants.java b/server/src/com/mirth/connect/client/core/BrandingConstants.java index b9d5cfe50..d7cc29761 100644 --- a/server/src/com/mirth/connect/client/core/BrandingConstants.java +++ b/server/src/com/mirth/connect/client/core/BrandingConstants.java @@ -9,4 +9,12 @@ public class BrandingConstants { public static final String CLIENT_CONNECTION_HEADER = "openintegrationengine-client"; public static final String SERVER_CERTIFICATE_CN = "oie-engine"; + + public static final String CONNECT_SERVER_URL = "https://connect.openintegrationengine.org"; + public static final String NOTIFICATIONS_URL = "https://api.github.com/repos/openintegrationengine/engine/releases"; + + public static final boolean CENTRAL_USER_REGISTRATION = false; + public static final boolean MANDATORY_USER_REGISTRATION = false; + public static final boolean CHECK_FOR_NOTIFICATIONS = true; + public static final boolean SEND_USAGE_STATISTICS = false; } diff --git a/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java b/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java index 426629f96..ea7e1efa3 100644 --- a/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java +++ b/server/src/com/mirth/connect/client/core/ConnectServiceUtil.java @@ -51,21 +51,27 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; + import com.github.zafarkhaja.semver.Version; + import com.mirth.connect.model.User; import com.mirth.connect.model.converters.ObjectXMLSerializer; import com.mirth.connect.model.notification.Notification; import com.mirth.connect.util.MirthSSLUtil; public class ConnectServiceUtil { - private final static String URL_CONNECT_SERVER = "https://connect.mirthcorp.com"; + private final static String URL_CONNECT_SERVER = BrandingConstants.CONNECT_SERVER_URL; private final static String URL_REGISTRATION_SERVLET = "/RegistrationServlet"; private final static String URL_USAGE_SERVLET = "/UsageStatisticsServlet"; - private static String URL_NOTIFICATIONS = "https://api.github.com/repos/openintegrationengine/engine/releases"; + private static String URL_NOTIFICATIONS = BrandingConstants.NOTIFICATIONS_URL; private final static int TIMEOUT = 10000; public final static Integer MILLIS_PER_DAY = 86400000; public static void registerUser(String serverId, String mirthVersion, User user, String[] protocols, String[] cipherSuites) throws ClientException { + if (!BrandingConstants.CENTRAL_USER_REGISTRATION) { + throw new UnsupportedOperationException("User Registration is disabled"); + } + CloseableHttpClient httpClient = null; CloseableHttpResponse httpResponse = null; NameValuePair[] params = { new BasicNameValuePair("serverId", serverId), @@ -107,6 +113,10 @@ public static void registerUser(String serverId, String mirthVersion, User user, * @throws Exception should anything fail dealing with the web request and the handling of its response */ public static List getNotifications(String serverId, String mirthVersion, Map extensionVersions, String[] protocols, String[] cipherSuites) throws Exception { + if (!BrandingConstants.CHECK_FOR_NOTIFICATIONS) { + throw new UnsupportedOperationException("Checking for Notifications is disabled."); + } + List validNotifications = Collections.emptyList(); Optional parsedMirthVersion = Version.tryParse(mirthVersion); if (!parsedMirthVersion.isPresent()) { @@ -208,6 +218,10 @@ protected static Notification toNotification(JsonNode node) { } public static int getNotificationCount(String serverId, String mirthVersion, Map extensionVersions, Set archivedNotifications, String[] protocols, String[] cipherSuites) { + if (!BrandingConstants.CHECK_FOR_NOTIFICATIONS) { + throw new UnsupportedOperationException("Checking for Notifications is disabled."); + } + Long notificationCount = 0L; try { notificationCount = getNotifications(serverId, mirthVersion, extensionVersions, protocols, cipherSuites) @@ -222,6 +236,10 @@ public static int getNotificationCount(String serverId, String mirthVersion, Map } public static boolean sendStatistics(String serverId, String mirthVersion, boolean server, String data, String[] protocols, String[] cipherSuites) { + if (!BrandingConstants.SEND_USAGE_STATISTICS) { + throw new UnsupportedOperationException("Sending Usage Statistics is disabled."); + } + if (data == null) { return false; } diff --git a/server/src/com/mirth/connect/server/Mirth.java b/server/src/com/mirth/connect/server/Mirth.java index 24c64874a..5e8cacfcf 100644 --- a/server/src/com/mirth/connect/server/Mirth.java +++ b/server/src/com/mirth/connect/server/Mirth.java @@ -401,8 +401,10 @@ public void startup() { printSplashScreen(); // schedule usage statistics to be sent at startup and every 24 hours - Timer timer = new Timer(); - timer.schedule(new UsageSenderTask(), 0, ConnectServiceUtil.MILLIS_PER_DAY); + if (BrandingConstants.SEND_USAGE_STATISTICS) { + Timer timer = new Timer(); + timer.schedule(new UsageSenderTask(), 0, ConnectServiceUtil.MILLIS_PER_DAY); + } } /** From 78c49639d8dd011c3427c45e6a7ebe433ede2b69 Mon Sep 17 00:00:00 2001 From: kayyagari Date: Thu, 12 Jun 2025 23:58:25 +0530 Subject: [PATCH 10/10] Changed version number to 4.5.2 Applied a custom icon for installer Changed configuration to stop the service before uninstallation Renamed media files --- .../install4j/oie-installer-config.install4j | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/tools/install4j/oie-installer-config.install4j b/tools/install4j/oie-installer-config.install4j index 217a717fa..e64158d1c 100644 --- a/tools/install4j/oie-installer-config.install4j +++ b/tools/install4j/oie-installer-config.install4j @@ -1,7 +1,7 @@ - - + + @@ -102,6 +102,16 @@ + + + + + ${compiler:installer:mediaRoot}/../governance/branding/icons/oie_logo_only_white_background_128x128.png + + + + + @@ -427,11 +437,28 @@ return true; + + + + + + + + + + + + + + 25 + + + @@ -713,25 +740,25 @@ return console.askYesNo(message, true); - + - + - + - + @@ -740,43 +767,43 @@ return console.askYesNo(message, true); - + - + - + - + - + - + - +