diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..16d875f
Binary files /dev/null and b/.DS_Store differ
diff --git a/build/.DS_Store b/build/.DS_Store
index 978b171..355d267 100644
Binary files a/build/.DS_Store and b/build/.DS_Store differ
diff --git a/build/config/default.json5 b/build/config/default.json5
index 21fc0bf..bd433c0 100644
--- a/build/config/default.json5
+++ b/build/config/default.json5
@@ -2480,6 +2480,7 @@
},
},
patientsPerPage: 25,
+ authEnabled: false,
timeout: 20000,
renderSelectedOnly: false,
fhirViewer: {
diff --git a/build/config/keycloak.json b/build/config/keycloak.json
new file mode 100644
index 0000000..0919ae0
--- /dev/null
+++ b/build/config/keycloak.json
@@ -0,0 +1,8 @@
+{
+ "realm": "test",
+ "auth-server-url": "https://localhost:8443/auth",
+ "ssl-required": "external",
+ "resource": "inferno",
+ "public-client": true,
+ "confidential-port": 0
+}
diff --git a/package.json b/package.json
index d6f72e7..5f3a27e 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
"if-env": "^1.0.0",
"jquery": "^3.2.1",
"json5": "^0.5.1",
+ "keycloak-js": "^17.0.0",
"less": "^2.7.2",
"less-loader": "^4.0.3",
"mixin-deep": "^1.2.0",
diff --git a/src/index.js b/src/index.js
index 4d410b4..e9f049f 100644
--- a/src/index.js
+++ b/src/index.js
@@ -8,27 +8,96 @@ import PatientList from "./components/PatientList";
import { Router, Route, Switch } from "react-router";
import createHistory from "history/createHashHistory";
import jQuery from "jquery";
+import Keycloak from "keycloak-js";
+import JSON5 from "json5";
+import { parseQueryString } from "./lib";
window.$ = window.jQuery = jQuery;
-const history = createHistory();
-
-ReactDOM.render(
-
-
-
-
-
-
-
-
-
- ,
- document.getElementById("main")
-);
-
-$(function () {
- $("body").tooltip({
- selector: ".patient-detail-page [title]",
- });
+let authEnabled = false;
+const DEFAULT_CONFIG = "default";
+let { config, ...params } = parseQueryString(window.location.search);
+
+jQuery.ajax({
+ url: `./config/${config || DEFAULT_CONFIG}.json5`,
+ dataType: "text",
+ cache: false,
+ async: false,
+ success: (json) => {
+ json = JSON5.parse(json);
+ authEnabled = json.authEnabled;
+ },
});
+
+if (authEnabled) {
+ let keycloak = new Keycloak("config/keycloak.json");
+
+ keycloak.onTokenExpired = function () {
+ keycloak.updateToken().then((refreshed) => {
+ if (refreshed) {
+ sessionStorage.setItem("access-token", keycloak.token);
+ }
+ });
+ };
+
+ keycloak
+ .init({
+ onLoad: "login-required",
+
+ scope: "patient/*.read",
+ })
+ .then(function (authenticated) {
+ if (authenticated) {
+ sessionStorage.setItem("access-token", keycloak.token);
+
+ const history = createHistory();
+
+ ReactDOM.render(
+
+
+
+
+
+
+
+
+
+ ,
+ document.getElementById("main")
+ );
+
+ $(function () {
+ $("body").tooltip({
+ selector: ".patient-detail-page [title]",
+ });
+ });
+ }
+ })
+ .catch(function () {
+ alert(
+ "Failed to initialize KeyCloak adapter. Check KeyCloak config file."
+ );
+ });
+} else {
+ const history = createHistory();
+
+ ReactDOM.render(
+
+
+
+
+
+
+
+
+
+ ,
+ document.getElementById("main")
+ );
+
+ $(function () {
+ $("body").tooltip({
+ selector: ".patient-detail-page [title]",
+ });
+ });
+}
diff --git a/src/lib/PatientSearch.js b/src/lib/PatientSearch.js
index 958ea28..631bebe 100644
--- a/src/lib/PatientSearch.js
+++ b/src/lib/PatientSearch.js
@@ -526,12 +526,12 @@ export default class PatientSearch {
.forEach((token) => {
if (token.indexOf("-") === 0) {
params.push({
- name: "_sort",
- value: token,
+ name: "_sort:desc",
+ value: token.substring(1),
});
} else {
params.push({
- name: "_sort",
+ name: "_sort:asc",
value: token,
});
}
@@ -836,18 +836,33 @@ export default class PatientSearch {
if (server.type == "DSTU-2") {
data = data.replace(/\bdeceased=(true|false)\b/gi, "");
}
-
- // prepare the base options for the patient ajax request
- let options = {
- url: `${server.url}/Patient/_search`,
- method: "POST",
- processData: false,
- data,
- headers: {
- accept: "application/fhir+json",
- "content-type": "application/x-www-form-urlencoded",
- },
- };
+ // Take Access token from session storage if its available ie. if KeyCloak enabled authentication enabled.
+ // And only include authorization header if access token is available
+ let keycloakToken = sessionStorage.getItem("access-token");
+
+ let options = keycloakToken
+ ? {
+ url: `${server.url}/Patient/_search`,
+ method: "POST",
+ processData: false,
+ data,
+ headers: {
+ accept: "application/fhir+json",
+ "content-type": "application/x-www-form-urlencoded",
+
+ authorization: "Bearer " + keycloakToken,
+ },
+ }
+ : {
+ url: `${server.url}/Patient/_search`,
+ method: "POST",
+ processData: false,
+ data,
+ headers: {
+ accept: "application/fhir+json",
+ "content-type": "application/x-www-form-urlencoded",
+ },
+ };
return this.getPatientIDs(server)
.then((ids) => {