Skip to content

Commit

Permalink
Deploying to gh-pages from @ 7c7bfe9 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
Aitem committed Dec 2, 2024
1 parent 24b8317 commit 4606a63
Show file tree
Hide file tree
Showing 7 changed files with 451 additions and 0 deletions.
11 changes: 11 additions & 0 deletions smart-app-launch/Dockerfile.growthchart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM docker.io/library/node:22

RUN git clone https://github.com/smart-on-fhir/growth-chart-app.git /app

WORKDIR /app

RUN npm install

EXPOSE 9000

CMD ["npm", "run", "start"]
65 changes: 65 additions & 0 deletions smart-app-launch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Launch growth-chart smart app on Aidbox and auth and login via KeyCloack



``` sh
docker compose up
```

aidbox - http://localhost:8080
keycloak - http://localhost:88888
growth-chart - http://localhost:9000

## EHR launch

### Patient launch

Open http://localhost:7070 (ehr emulator)


Need launch uri

``` curl-config
POST /rpc
method: aidbox.smart/get-launch-uri
params:
user: patient
iss: http://localhost:8080
client: growth_chart
ctx:
patient: patient
```

http://localhost:9000
login using KeyCloack
username: provider
password: provider

### Provider launch

``` curl-config
POST /rpc
method: aidbox.smart/get-launch-uri
params:
user: provider
iss: http://localhost:8080
client: growth_chart
ctx:
patient: patient
```

## Stand alone launch

### Patient launch

`user.fhirUser` should be ref to Patient

http://localhost:9000
login using KeyCloack
username: patient
password: patient


### Provider launch - not supported
56 changes: 56 additions & 0 deletions smart-app-launch/aidbox.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"type": "transaction",
"entry": [
{
"request": {
"method": "PUT",
"url": "/Client/growth_chart"
},
"resource": {
"resourceType": "Client",
"id": "growth_chart",
"auth": {
"authorization_code": {
"redirect_uri": "http://localhost:9000/",
"refresh_token": true,
"token_format": "jwt",
"access_token_expiration": 3600000
}
},
"smart": {
"launch_uri": "http://localhost:9000/launch.html"
},
"type": "smart-app",
"secret": "quOfCRS7ty1RMUQq",
"grant_types": [
"authorization_code"
]
}
},
{
"request": {
"method": "PUT",
"url": "/IdentityProvider/keycloak"
},
"resource": {
"resourceType": "IdentityProvider",
"scopes": [
"profile",
"openid"
],
"system": "keycloak",
"userinfo_endpoint": "http://localhost:8888/realms/patients/protocol/openid-connect/userinfo",
"authorize_endpoint": "http://localhost:8888/realms/patients/protocol/openid-connect/auth",
"client": {
"id": "aidbox",
"secret": "HOuPXmduHfTjhtW0eqAeMsHZJbRNVc8x"
},
"title": "Keycloak",
"active": true,
"id": "keycloak",
"token_endpoint": "http://keycloak:8888/realms/patients/protocol/openid-connect/token",
"userinfo-source": "id-token"
}
}
]
}
63 changes: 63 additions & 0 deletions smart-app-launch/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
version: '3.7'
volumes:
aidbox_pg_data: {}

services:

growth_chart:
build:
context: .
dockerfile: ./Dockerfile.growthchart
ports:
- 9000:9000

keycloak:
image: quay.io/keycloak/keycloak:26.0.6
volumes:
- ./keycloak.json:/opt/keycloak/data/import/keycloak.json
ports:
- 8888:8888
environment:
KC_HTTP_PORT: 8888
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
command: start-dev --import-realm

aidbox_db:
image: healthsamurai/aidboxdb:17
volumes:
- aidbox_pg_data:/data:delegated
environment:
PGDATA: /data
POSTGRES_USER: aidbox
POSTGRES_PORT: '5432'
POSTGRES_DB: aidbox
POSTGRES_PASSWORD: nP0s8ALcTk

aidbox:
image: healthsamurai/aidboxone:edge
depends_on:
- aidbox_db
ports:
- 8080:8080
volumes:
- ./aidbox.json:/tmp/aidbox.json
environment:
BOX_INIT_BUNDLE: file:///tmp/aidbox.json
AIDBOX_TERMINOLOGY_SERVICE_BASE_URL: https://tx.fhir.org/r4
AIDBOX_FHIR_PACKAGES: hl7.fhir.r4.core#4.0.1
AIDBOX_FHIR_SCHEMA_VALIDATION: true
AIDBOX_CREATED_AT_URL: https://aidbox.app/ex/createdAt
AIDBOX_CLIENT_SECRET: vbDPgXnz0H
AIDBOX_CORRECT_AIDBOX_FORMAT: true
AIDBOX_ADMIN_PASSWORD: password
AIDBOX_COMPLIANCE: enabled
BOX_SEARCH_FHIR__COMPARISONS: true
PGHOST: aidbox_db
BOX_COMPATIBILITY_VALIDATION_JSON__SCHEMA_REGEX: '#{:fhir-datetime}'
PGUSER: aidbox
AIDBOX_PORT: 8080
PGDATABASE: aidbox
PGPASSWORD: nP0s8ALcTk
PGPORT: '5432'
BOX_SEARCH_INCLUDE_CONFORMANT: true
158 changes: 158 additions & 0 deletions smart-app-launch/ehr.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<!DOCTYPE html>
<html>
<head>
<title>FHIR Patient List</title>
</head>
<body>

<h1>EHR Emulator</h1>

<form id="loginForm">
<h2>Login</h2>
<label>
Username: <input type="text" id="username" required />
</label><br/>
<label>
Password: <input type="password" id="password" required />
</label><br/>
<button type="submit">Login</button>
</form>
<div id="patientList" style="display:none;">
<h1>Patient List</h1>
<div id="user-info"></div>
<ul id="patients"></ul>
</div>

<script>
let accessToken = '';

// const username = 'provider';
// accessToken = '';
// showUserInfo(username);
// const fhirUrl = 'http://localhost:8080/fhir/Patient?_count=20&birthdate=ge2000'; // Replace with your FHIR server endpoint
// fetch(fhirUrl, {method: 'GET', headers: {'Authorization': 'Bearer ' + accessToken}})
// .then(response => response.json())
// .then(fhirData => {displayPatients(fhirData);})
// .catch(error => {console.error('Error fetching patients:', error);});

document.getElementById('loginForm').addEventListener('submit', function(e){
e.preventDefault();

const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const client_id = 'ehr'; // Replace with your client_id

// Token endpoint URL
const tokenUrl = 'http://localhost:8080/auth/token'; // Replace with your token endpoint

// Prepare data for token request
const data = new URLSearchParams();
data.append('grant_type', 'password');
data.append('username', username);
data.append('password', password);
data.append('client_id', client_id);
// data.append('client_secret', client_secret);


// Request an access token
fetch(tokenUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data.toString()
})
.then(response => response.json())
.then(tokenData => {
if(tokenData.access_token){
showUserInfo(username);
accessToken = tokenData.access_token;
// Use the access token to fetch patients
const fhirUrl = 'http://localhost:8080/fhir/Patient?_count=20&birthdate=ge2000';
fetch(fhirUrl, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + tokenData.access_token
}
})
.then(response => response.json())
.then(fhirData => {
displayPatients(fhirData);
})
.catch(error => {
console.error('Error fetching patients:', error);
});
} else {
console.error('Authentication failed:', tokenData);
alert('Authentication failed: ' + (tokenData.error_description || 'Unknown error'));
}
})
.catch(error => {
console.error('Error during authentication:', error);
});
});

function showUserInfo(username) {
const userInfo = document.getElementById('user-info');
userInfo.innerHTML = 'You logged in as ' + username;
}

function launch(token, patientId) {
const fhirUrl = 'http://localhost:8080/rpc';
let body = {
method: "aidbox.smart/get-launch-uri",
params: {
user: "practitioner",
iss: "http://localhost:8080/fhir",
client: "growth_chart",
ctx: {patient: patientId}
}
}
fetch(fhirUrl, {
method: 'POST',
headers: {'Authorization': 'Bearer ' + token,
'content-type': 'application/json'},
body: JSON.stringify(body)
})
.then(response => response.json())
.then(resp => {
// console.log("resp", resp)
window.location = resp.result.uri
})
.catch(error => {
console.error('Error fetching patients:', error);
});
}

function displayPatients(fhirData){
document.getElementById('loginForm').style.display = 'none';
document.getElementById('patientList').style.display = 'block';

const patientsUl = document.getElementById('patients');
patientsUl.innerHTML = '';

if(fhirData && fhirData.entry){
fhirData.entry.forEach(function(entry){
const patient = entry.resource;
let name = 'Unknown';
let id = patient.id;
if(patient.name && patient.name.length > 0){
const nameObj = patient.name[0];
const given = nameObj.given ? nameObj.given.join(' ') : '';
const family = nameObj.family || '';
const birthDate = patient.birthDate || '';
name = `${given} ${family} (${birthDate}) <span style="color: blue" onclick="launch('${accessToken}', '${id}')">Launch Growth chart app</span>`;
}
const li = document.createElement('li');
li.innerHTML = name;
patientsUl.appendChild(li);
});
} else {
const li = document.createElement('li');
li.textContent = 'No patients found.';
patientsUl.appendChild(li);
}
}
</script>
</body>
</html>
17 changes: 17 additions & 0 deletions smart-app-launch/init.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"resourceType" : "Bundle",
"type" : "transaction",
"entry" : [
{
"request": {
"method": "PUT",
"url": "/Patient/marat-test-init-bundle"
},
"resource" : {
"resourceType" : "Patient",
"id" : "marat-test-init-bundle",
"gender": "male"
}
}
]
}
Loading

0 comments on commit 4606a63

Please sign in to comment.