Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

smart.user for Epic's OpenID Connect id_tokens? #105

Closed
Worble opened this issue Nov 23, 2020 · 3 comments
Closed

smart.user for Epic's OpenID Connect id_tokens? #105

Worble opened this issue Nov 23, 2020 · 3 comments

Comments

@Worble
Copy link

Worble commented Nov 23, 2020

Hi, I was just wondering if there was the potential for the shorthand smart.user to support Epic's user process? Apologies if this is already supported, I couldn't see any way to activate it.
As outlined here: https://apporchard.epic.com/Article?docId=oauth2&section=Embedded-Oauth2-Launch_ID-Tokens
Assuming the client is on R4 and has requested the openid and fhirUser scopes, the id_token returned after the oauth response will have fhirUser in it's payload, which will be an absolute reference to the FHIR resource.
At the moment this just manifests in a small workaround:

let user;
if (smart.user.id) {
	user = await client.user.read();
} else {
	user = await client.request(JSON.parse(atob(smart.state.tokenResponse.id_token.split(".")[1])).fhirUser);
}

But it would be nice to just have the one await smart.user.read();

@vlad-ignatov
Copy link
Collaborator

That should be doable like so:

FHIR.oauth2.ready()
    .then(async (client) => {
        client.user.fhirUser; // A string lik "Practitioner/abc" or null
        client.user.getFhirUser(); // Getter for the above
        client.user.id; // A string like "abc" or null
        client.user.getUserId(); // Getter for the above
        client.user.resourceType; // String like "Practitioner", "Patient" etc, or null
        client.user.getUserType(); // Getter for the above
        client.user.read(); // rejects if there is no user

        // Real example:
        if (client.user.id) {
            const userResource = await client.user.read();
        } else {
            console.log("no user");
        }
    });

@azjawinski
Copy link

azjawinski commented Mar 10, 2021

@vlad-ignatov I have a different problem - it looks like Epic does not use the old profile key in idtoken and instead passes only fhirUser. Additionally, it returns a complete absolute path to the resource rather than only the FHIR identifier. Maybe some option for easy configuration of these would be beneficial?

Example Epic Sandbox response:

{
aud: "111"
exp: 111
fhirUser: "https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/Practitioner/111"
iat: 111
iss: "https://fhir.epic.com/interconnect-fhir-oauth/oauth2"
sub: "111"
}

The code fails, because you are checking only the profile field, which is deprecated.

Faulty code:

return idToken.profile;

Current workaround:

SMART.ready().then(
      (_client) => {
        // Manual fix for lib not supporting `fhirUser` field
        _client.getFhirUser = function () {
          const idToken = this.getIdToken();

          if (idToken) {
            if (idToken.hasOwnProperty("profile")) {
              return idToken.profile;
            } else if (idToken.hasOwnProperty("fhirUser")) {
              // Epic returns absolute URL, extract only the FHIR Resource part
              const fhirUser = idToken.fhirUser.split("/").slice(-2).join("/");
              return fhirUser;
            }
          }

          return null;
        };
        // End of manual lib fix
        setClient(_client);
      },
      (_error) => setError(_error)
    );

Not sure what is the situation for FHIR older than R4.

vlad-ignatov added a commit that referenced this issue Jun 10, 2021
@vlad-ignatov
Copy link
Collaborator

A fix is included in 2.4.0. Feel free to re-open if you have further issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants