GithubHelp home page GithubHelp logo

smart-on-fhir / client-js Goto Github PK

View Code? Open in Web Editor NEW

This project forked from jmandel/fhir-js-client

284.0 31.0 199.0 23.46 MB

JavaScript client for FHIR

License: Other

JavaScript 18.35% TypeScript 80.75% HTML 0.90%

client-js's Introduction

SMART on FHIR JavaScript Library

This is a JavaScript library for connecting SMART apps to Fhir servers. It works both in browsers (IE10+) and on the server (NodeJS).

Installation

Install from npm:

npm i fhirclient

Documentation

The documentation for the upcoming release is available at http://docs.smarthealthit.org/client-js/.

Check out what's new in v2!


Contributing and Development

NPM Scripts

After you cd into to the project folder and run npm i, you can use npm scripts to handle any project-related task:

# run tests
npm test

# Build everything
npm run build

# Build all bundles (browser packages in dist/build)
npm run pack

# Build the CommonJS modules (for Node and bundlers)
npm run build:module

License

Apache 2.0

client-js's People

Contributors

bently0602 avatar clintharrison avatar djake avatar dtphelan1 avatar gimbalgambit avatar ginocanessa avatar icon5585 avatar jaymaiurano avatar jmandel avatar kolkheang avatar ngourley avatar nschwertner avatar shriniketsarkar avatar timothyakampa avatar vlad-ignatov avatar zplata avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

client-js's Issues

Publish beta to npm with beta tag

Hi there ๐Ÿ‘‹

I'm one of the devs working on OpenMRS' EMR system. We're starting a redesign of the frontend and are exploring if/how much/what it would take to use smart-on-fhir. Main limitation is that openmrs backend doesn't have full support for it.

I'm glad to see that v2 of this project uses Promises instead of jquery deferred objects and am excited that this repo has active development.

It would be helpful to publish v2 to npm with a beta npm dist-tag so that consumers can easier control upgrades to new versions of the beta. Additionally it would let my npm install only include the built files and runtime dependencies instead of how it currently installs all the babel and other dependencies that are specified in the shrinkwrap.

install from npm:
Screen Shot 2019-06-11 at 7 01 59 PM

install from github:
Screen Shot 2019-06-11 at 7 05 25 PM

TypeError: Cannot read property 'substr' of undefined at stripTrailingSlash

I receive a somewhat vague error when using this client to communicate with an auth server:

TypeError: Cannot read property 'substr' of undefined at stripTrailingSlash

From what I can tell, this is caused by fhirServiceUrl missing a value. Would it be possible to catch for an error here, and produce a more useful error message?

Implementation of a client-dart?

Hi all,

This might not be the best way of asking, because it is not really an issue, so sorry about that, I can start a thread in a more appropriate place if you point me there.

I am planning to start writing a client based on Dart, but with all the great work punt into other clients, I am curious what should be my starting point, either this client-js or the client-ts

Thank you

Support Authorization Workflow in a New Window

The current authorization workflow only support authorization flow in the same window. It does not support launching a new window for the authorization flow.

The library should allow the authorization flow to be done in a separate window for a better user experience; and also to support a use case where the app is embedded in an iframe. During the authorization flow, the server may present an authorization request to the user. If the application is embedded in an iframe, the user will not be able to see the authorization request due to the X-Frame-Options header.

The consumers of this library should have the ability to specify whether the authorization flow should be in a new window or embedded using the same window.

Can't install package

@vlad-ignatov Thank you so much for the great work recently on this lib!! ๐Ÿฅ‡

Have you published the package yet? npm i client-js fails and I don't see client-js in the npm registry

TypeError: Cannot read property 'client' of undefined in version 2.1.1

Upgrading from v2.1.0 to 2.1.1 causes the error TypeError: Cannot read property 'client' of undefined when using FHIR.client directly.

Not sure if it makes a difference, but FHIR is used within a VueJS app (v2.6.11), e.g.:

<template>
  <div id="app">
  </div>
</template>

<script>
import FHIR from "fhirclient";

export default {
  name: "App",
  components: {
  },
  async mounted() {
    const client = FHIR.client("http://hapi.fhir.org/baseR4");
    const bundle = await client.request("Patient");
    console.log(bundle);
  }
};
</script>
vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'client' of undefined
    at VueComponent.mounted (App.vue?234e:18)
    at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
    at callHook (vue.runtime.esm.js?2b0e:4219)
    at Object.insert (vue.runtime.esm.js?2b0e:3139)
    at invokeInsertHook (vue.runtime.esm.js?2b0e:6346)
    at Vue.patch [as __patch__] (vue.runtime.esm.js?2b0e:6565)
    at Vue._update (vue.runtime.esm.js?2b0e:3945)
    at Vue.updateComponent (vue.runtime.esm.js?2b0e:4066)
    at Watcher.get (vue.runtime.esm.js?2b0e:4479)
    at new Watcher (vue.runtime.esm.js?2b0e:4468)

IE11 Invalid character Error

Hi,

I'm using fhir-client v0.1.15 to develop a SMART on FHIR web application that would run in EHR launch scenario. For example in Epic Hyperspace simulator that uses IE to run the SMART application.

While testing my application locally on IE11, I get a JavaScript error from within fhir-client.js.

SCRIPT1014: Invalid character
File: fhir-client.js, Line: 38113, Column: 3

Below are the two lines from code. 38112 & 38113 in order:

  var ret = Adapter.get().defer();
  var state = JSON.parse(sessionStorage[params.state]);

Any solution or workaround would be much appreciated.

Post on SO with bounty.

Cannot find namespace 'fhirclient'

I import 'fhirclient' node module in my angular project, it shows me this error message when I build the project. Please find the attachment for the error message.
import { oauth2 as SMART } from "fhirclient";

Screenshot 2019-09-16 at 5 13 18 PM

Please help with this issue.

Await + onPage together

await client.request("/Patient", {
    pageLimit: 5,
    onPage(bundle) {
        // do something with the downloaded page
    }
});

What does the outer await eventually return? An array of pages? There are some docs below but it'd be good to include (with comments) in this snippet some use of the returned array.

If onPage returns a promise it will be awaited for.

This isn't quite clear: waited for at what stage?

To fetch all the available pages you can set this to 0

If I use pageLimit: 0 and onPage, do all the results still get aggregated into an (arbitrarily large) in-memory array to resolve the top-level promise?

State param not available after redirect

After the redirect happens the state param on the url seems to disappear in our application. It does get set as the redirect url however when login is complete the state param is gone.

I did see in smart.js line:247 that you try to retrieve the state key if no key is set on the url. however a sessionStorage with "SMART_KEY" never gets set in authorize().

I was able to work around this by adding the state to sessionStorage with the smart_key in authorize() and then setting the key in completeAuth() like this

if (!key) {
        const tempState = await Storage.get(SMART_KEY);
        key = tempState.key
    }

this seems like a bit of a hack and there is probably an issue i am not seeing with the redirect.

URL introspection?

Hello,
Is there a way to introspect the URL that fhirclient is current set to? I'm asking in regards to multi-vendor applications, and how to flex the search queries based on an incoming iss URL parameter. I'm trying to do something like the following:

import { oauth2 as SMART } from "fhirclient";

// assuming that SMART.ready() has been called already
function fetchSomeData(){
  const observationQuery = new URLSearchParams();
  console.log('Observations Query', observationQuery);

  // FEATURE REQUEST:  could we have something like the following?  
  let url = SMART.getCurrentUrl();
  if(url.includes("epic")){
    observationQuery.set("patient", client.patient.id);
  } else if (url.includes("cerner")){
      observationQuery.set("subject", client.patient.id);
  } 
  
  let observationUrl = 'Observation?' + observationQuery.toString()
  console.log('observationUrl', observationUrl);
    
  client.request(observationUrl, {
    pageLimit: 0,
    flat: true
  }).then(observations => {
   doSomeStuff(observations)
  });
}

Is there are alternative approach or workaround that can achieve the same thing?

This is a real world example, by the way. Where Cerner wants to normalize the query parameters to use the patient search alias, while Epic is adhering more to FHIR schema and ignoring the search option alias.
Thanks!!!

resolveReferences not works in nested array

organization sample

{
"resourceType": "Organization",
"id": "1",
"meta": {
"versionId": "1",
"lastUpdated": "2020-02-06T02:21:21.768-05:00"
},
"identifier": [
{
"use": "official",
"type": {
"text": "License"
},
"value": "PS002",
"period": {
"start": "2019-01-01T00:00:00.000Z",
"end": "2025-12-31T23:59:59.000Z"
},
"assigner": {
"reference": "Organization/2"
}
}
],
"active": false,

"name": "test Org"
}

I trying to load resource (organization) contains multiple identifier inside each identifier entity assigner (I need to load all identifier assigner )


I pass option
resolveReferences: ["identifier.assigner"]

return references: {}

on hapi server, redirectUri always set to http, never https

I'm working on app orchard integration using hapi js server ([email protected]) and found that the requst makes to the authorize endpoint with the redirectUri with http scheme. I took a look at the code and found that the issue was from NodeAdapter.js, line 56 where the req.protocol is always undefined for the hapi server. the possosible solution is to add the use of this._request.url.protocol for the hapi server.

TypeError: getRef(...).then is not a function

Hi! Started using the library in the React Native project today and run into a problem with resolveReferences. This is the request:
client.request('Encounter', {pageLimit: 0, flat: true, resolveReferences['subject']})
And suddenly request crashes when getRef returns result object instead of a promise. Looks like it's a fetch caching thing and promise resolves faster than loop finishes resolving references. Here is the stack trace:

TypeError: getRef(...).then is not a function
at eval (Client.js:111)
at Array.map ()
at resolveRef (Client.js:107)
at eval (Client.js:178)
at Array.map ()
at eval (Client.js:177)
at tryCallOne (core.js:37)
at core.js:123
at JSTimers.js:289
at _callTimer (JSTimers.js:146)

What am I doing wrong and how to fix this?
Not sure if this will help but is it possible to ignore fetch caching for all requests? Seems like setting headers for client.request doesn't inherit to subsequent requests for resolving references.

Refresh token call needs with credentials

In addition to issue #17, making the client apply refresh tokens automatically, my collaborator @rmchndrng had to create a fork to add withCredentials to support the refresh workflow here: rmchndrng@17d7657

Thank you for all of your work on this!

We are currently trying to use your JS library for a large scale RCT trial out of Columbia. :)

No token when launching from within EHR sandbox

We're trying to load the application within Epic's AppOrchard sandbox and keep running into an issue where the OAuth flow is aborted before getting a token. The same issue is not happening in EHRs opening in their own tabs or in standalone mode.

For the SMART auth flow, I originally used init which kept caching the initial result without a token response. In light of that, I switched back to using authorize and then ready.

Then, I noticed a few things that still were causing some issues:

  1. in the authorize method in smart.js params.target is always undefined instead of having a default as specified in the docs. Would this cause logic problems further down the line?

  2. in the authorize method in smart.js on line 343, I think it should be if (win == self) { instead of if (win !== self) {. Without this, it doesn't seem like the event listener would get added correctly.

  3. in the completeAuth method in smart.js on line 472, the parent.postMessage event is either not happening or there is an issue with the listener. I tried to substitute that for every possibility from the 'postMessage' API, but nothing seemed to work there. By moving the onMessage functionality in there and bypassing the event, my app was able to successfully authenticate in the EHR sandbox.

TS4090: Conflicting definitions for 'node'

I'm running Aurelia 1.3.1, this happens on clean install.

If I have a definition in packages.json "@types/node": "^10.11.6", the following error will appear when trying to run the framework:

TS4090: Conflicting definitions for 'node' found at 'D:/dev/my_project/node_modules/@types/node/ts3.2/index.d.ts' and 'D:/dev/my_project/node_modules/fhirclient/node_modules/@types/node/ts3.5/index.d.ts'. Consider installing a specific version of this library to resolve the conflict.

The bug is intermittent, as it sometimes may not appear. Deleting the 'node' folder from either place stops the error from appearing.

quicker or custom timeouts for .well-known/smart-configuration ?

Hi --

I've been trying to connect to epic patient apis ... often there is no

.well-known/smart-configuration endpoint and you get a 404

But it seems like this takes a few seconds, which makes it seems like the webapp itself is unresponsive to users.

Anyway to set a custom timeout for the well-known request? Like 1second or so ... seems like metadata is usually available but i get a lot of bounces from people thinking that the app itself is not working when it is really waiting for a 404 to return for the well-known request.

Thanks,
k.

Support additional default accept headers: application/fhir+json, application/json+fhir

Currently the default accept header for all FHIR requests is application/json. The spec for STU 3 is using application/fhir+json and the current DSTU 2 is application/json+fhir.

The library should default in the appropriate accept headers and let each implementation of FHIR server deal with content negotiation properly. This way the client will get the correct content specified.

This can be done here or during initialization by passing the accept header values in order.

Debug output to Console.

According to some documentation I found one should set localStorage.setItem("debug", "FHIR.*") to get debug info to console. This works fine for the FHIR.oauth2.ready() call, but not for FHIR.oauth2.authorize.

The applicaion I have is a React app with separate launch and redirect pages. I have tried setting localstorage debug="FHIR.*" for both.

Errors while retrieving refresh and/or access token

We're developing smart app using react & fhir-client and we are seeing following errors if user doesn't interact with app for long time.

  1. 'failed to exchange code for access_token'
  2. 'Failed to exchange refresh token for access token'

They are not that frequent but it would be nice if there's any workaround with this errors rather than having user relaunch the application.

CC: @vlad-ignatov

fhir-client.js failed on unsecured/open client

When using the latest fhir-client.js (v 0.1.11) with unsecured client (client that doesn't do Oauth2), BBClient.ready() function failed at line 17167. The reason is that unsecured client doesn't have access_token. So the payloadCheck object is null and the code section at line 17167 payloadCheck['exp'] crashes the process.

When I say unsecured client, I mean the client that bypass OAuth2 authentication. The server url is send to launch page using fhirServiceUrl parameter.

Environment: Windows 7 , VS 2015, MVC ASP.NET 4.5.2, fhir-client.js 0.1.11

online_access support

The specification provides for an online_access scope as well as an offline_access scope - both result in a refresh_token being returned in then the token request (see the spec for the different use cases)

[http://www.hl7.org/fhir/smart-app-launch/scopes-and-launch-context/index.html]

Currently, the code in Client.js has this:


    if (scopes.indexOf("offline_access") == -1) {
      throw new Error("Unable to refresh. No offline_access scope found.");
    }

It would see that this is incorrect - it should be able to refresh with either offline_access or online_access.

Support of non JWTs (JSON Web Tokens), additional authorization params & TS-wrapper

Hi there

First of all, I would like to thank for the library and the awesome tutorials and documentation on http://docs.smarthealthit.org/authorization/.

The authorization documentation (http://docs.smarthealthit.org/authorization/) in chapter "SMART authorization and resource retrieval" part three "App exchanges authorization code for access token" says:

"Defining the format and content of the access token is left up to the organization that issues the access token and holds the requested resource."

But now, as far as I understood it from debugging, the bb-client ready function expects a jw token (after successful authentication with a "validTokenResponse").

Line 301 of bb-client in src folder:
var payloadCheck = jwt.decode(tokenResponse.access_token);

Without a JSON Web Token the app crashes on the next line, cause there is no key 'exp' in the decoded non-jwt token that returned 'null' (means var payloadCheck === null).

I would like to ask, if there is already a plan to make the client-js library work with non-jwts or if there is any workaround?


My second request/question is; is there a way to add additional request body params during the "completeCodeFlow"?

Line 126-130 lines in the bb-client.js:

if (state.client.secret) { 
    headers['Authorization'] = 'Basic ' + btoa(state.client.client_id + ':' + state.client.secret);
} else {
    data['client_id'] = state.client.client_id;
}

Our oAuth 2.0 server expects always the client_id in the body. Even if there is a client_secret. Would it be possible to implement a functionality that makes it possible to select/define which way the params will be sent?

The oAuth 2.0 documentation (https://tools.ietf.org/html/rfc6749) says that the request header with Authorization should be the default way and the parameters in the request body is the alternative.

For example (with extra line breaks for display purposes only):

 `Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3`

Alternatively, the authorization server MAY support including the
client credentials in the request-body using the following
parameters:

client_id
REQUIRED. The client identifier issued to the client during
the registration process described by Section 2.2.

client_secret
REQUIRED. The client secret. The client MAY omit the
parameter if the client secret is an empty string.


In addition, I would like to ask, if there is a plan to make an TypeScript version of this library or if there is a "TS-Wrapper" for it?

Many thanks and greeting

IE11: State param not available after redirect

Hi,

FHIRClient Version: 2.1.0

Works in Chrome and Edge but having an issue in IE11 where state param is not found due to null key.

Not sure why the key isn't there anymore but it's similar to this issue 48

Is there already a fix for this or is it better to revert to the V1 release for now?

Vue App
DSTU2
fhirclient 2.1.0
IE 11

TIA

Refresh token needs offline access scope to work?

Hi --

I was using v2 in a webapp ... but when i call client.refresh() I get following error:

Uncaught Error: Unable to refresh. No offline_access scope found.

I was looking to refresh the token when the webapp is left open (I think Cerner's tokens last about 9.5 minutes or something)

Is there a way to refresh the token in webapp ... or do you need offline scope?

Thanks,
kevin.

Not working in IE

I am creating an app with Vue.js,
Apps works fine in IE 11 before i install the package from npm and use in my Vue.js code then i got this error
image

Question: bypass auth

Hi there,

Is there a way to bypass oauth or all auth mechanisms? In the source I can see provisions for that but I'm not sure how to configure the client in this way and can't find any documentation on this.

Kind regards,

fakeTokenResponse not working

I am trying to utilize the fakeTokenResponse documented here: http://docs.smarthealthit.org/client-js/api.html

FHIR.oauth2.authorize({
	'response_type': 'code',
	'clientId': clientId,
	'redirectUri': redirectUri,
	'state': generateStateValue(),
	'fakeTokenResponse': fakeTokenResponse, // Object with data
	'scope': 'launch online_access openid profile launch/patient patient/Patient.read'
});

However, the tokenResponse I receive is an actual tokenResponse, not the fake token that I created. There is not much documentation on this option, and I can't find examples of anyone else using it. Am I doing this correctly?

I'd like to be able to insert this token so that I can use my own test data as a response, instead of the token I receive from the client.

javscript error on calling fetchAllWithReferences

hey guys,

the search API works but I would like to use fetchAllWithReferences to get some of the referenced objects as well along with med orders.

The error i'm getting is

SCRIPT438: Object doesn't support property or method 'startsWith'
File: fhir-client.js, Line: 1221, Column: 22

pt.api.fetchAllWithReferences(
        { type: "MedicationOrder" },
        [ "MedicationOrder.reasonReference" ]
    ).then(function(dt){
        console.log("retrieved medications");
        console.log(dt);
   }).fail(function(err){
        console.log('error in retrieving medications');
        console.log(err);
    }); 

Is this a known issue? or am I doing anything wrong? I'm targeting DSTU2 sandbox.

Thanks in advance

PKCE support for public SMART app authorization code flow

Hey team
Our OAuth2 Vender only supports public application Authorization Code flow with PKCE support. Which current client-js does not have the functionality.

To enable this feature for our SMART App usage. We have implemented it in a forked version of client-js at https://github.com/t-zhao/client-js. (commit)

It will be great if we could contribute this back to your repo. And we want to have to your opinion first and recommendations for next step.

Thanks
Tong

Explain relation to fhir.js

Since v2.0.0 this library no longer includes fhir.js. That architecture was extremely difficult to maintain. However, it is still possible to use fhir.js.

Is fhir.js needed, or is the equivalent/relevant functionality already available in this library? It would be good to say something like "there is no need to use fhir.js; the necessary functionality comes built in to the SMART client" if that's the case.

Publish version that does not include core-js

I'd prefer to be able to choose whether to include core-js into my application, in favor of choosing whether/what/how to polyfill. After cloning this repo and removing core-js, it reduced the prod bundle size for v2 from 100kb to 50kb -- would be nice if I had the choice to use fhir-client without those extra 50kb

error when response body is empty

While creating a resource on Cerner FHIR DSTU2 server, the reponse from server has empty body. fhir-client.js return error because body is emtpy.

aud parameter

Is there a reason why aud is always set to the server url? Would it be possible to extend the options for authorize to manually set aud?

Remove jquery/angular

Is there any reason this is supporting such dated libraries?

Why not use fetch with an optional shiv for compatibility?

The latest version of browserify produces incompatible code for IE10

Version 16.2.3 of browserify npm package included as a dependency of this project does not generate code that is compatible with IE10.

When /dist/fhir-client.js file is loaded in an IE10 environment, the following error is produced.

Line: 8961

Object doesn't support property or method 'write'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.