npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@healthcloudai/hc-login-connector

v0.0.11

Published

Healthcheck Login authentication SDK with TypeScrip and token refresh

Downloads

838

Readme

Healthcheck Login Connector

This library provides a tenant-aware client for patient registration, onboarding, authentication, password reset flows, token refresh, authenticated patient context retrieval, and local auth helper methods.

The connector is built on top of the shared Healthcheck HTTP layer, and the examples below follow the current behavior implemented in src/client.ts.


Features

  1. Patient registration with tenant-scoped request payloads
  2. Generic onboarding step submission through submitOnboardingStep(...)
  3. Convenience helpers for email verification and SMS verification steps
  4. Convenience helpers for health profile and address onboarding steps
  5. Patient login with in-memory access, refresh, and ID token storage
  6. Password reset initiation and password reset confirmation
  7. Access token, ID token, tenant, and base URL helper methods
  8. Token refresh using the current authenticated token state
  9. Authenticated patient header retrieval through getUserInfo() and getHeader()
  10. Built on the shared Healthcheck HttpClient layer

Installation

npm install @healthcloudai/hc-login-connector \
@healthcloudai/hc-http

Import

import { HCLoginClient } from "@healthcloudai/hc-login-connector";
import { FetchClient } from "@healthcloudai/hc-http";

Usage

Configuration

Call configure() before any other method. It stores the tenant configuration locally on the client instance, and the same configured client should be reused across registration, onboarding, login, refresh, and authenticated calls.

const httpClient = new FetchClient();
const loginClient = new HCLoginClient(httpClient);

loginClient.configure("demo-tenant", "dev");
// The current source signature also accepts an optional region argument:
// loginClient.configure("demo-tenant", "dev", "region-code");

Full API request

configure() does not send an HTTP request. The configuration example above updates local client state only.

API response

configure() does not receive an API response. It stores the tenant configuration locally for later requests.


Methods

Get Base URL

Public signature: loginClient.getBaseUrl()

Returns the base URL derived from the current configuration.

const baseUrl = loginClient.getBaseUrl();

Full API request

getBaseUrl() does not send an HTTP request. The usage example above reads the value from local state.

API response

getBaseUrl() returns the currently configured base URL from local state.

https://dev-api-healthcheck.healthcloud-services.com/api

Get Tenant ID

Public signature: loginClient.getTenantId()

Returns the tenant ID currently stored by configure(...).

const tenantId = loginClient.getTenantId();

Full API request

getTenantId() does not send an HTTP request. The usage example above reads the value from local state.

API response

getTenantId() returns the configured tenant ID from local state.

demo-tenant

Submit Onboarding Step

Public signature: loginClient.submitOnboardingStep(step, user, data?, language?)

This is the step-driven onboarding API. The selected step determines the final shape of Data.User, and TenantID is injected internally from configure(...). Callers should provide only the fields relevant to the selected step.

Supported steps:

  • EMAIL_VERIFY
  • RESEND_EMAIL_VERIFY
  • RESEND_SMS_VERIFY
  • SMS_VERIFY
  • SAVE_HEALTH_PROFILE
  • SAVE_ADDRESS
await loginClient.submitOnboardingStep(
  "SAVE_HEALTH_PROFILE",
  {
    Email: "[email protected]",
    FirstName: "John",
    LastName: "Doe",
    BirthDate: "1990-01-01",
    Gender: "male",
    Race: "White",
    Ethnicity: "Not Hispanic or Latino",
    Status: 0,
    Sex: "Male"
  },
  "",
  "en"
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "",
    "Step": "SAVE_HEALTH_PROFILE",
    "User": {
      "Email": "[email protected]",
      "TenantID": "demo-tenant",
      "FirstName": "John",
      "LastName": "Doe",
      "BirthDate": "1990-01-01",
      "Gender": "male",
      "Sex": "Male",
      "Status": 0,
      "Race": "White",
      "Ethnicity": "Not Hispanic or Latino"
    },
    "Language": "en"
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Register

Public signature: loginClient.register(email, password, firstName?, lastName?, options?)

Registers a patient for the configured tenant.

TenantID is injected internally from configure(...).

options.attributes can be used to pass arbitrary additional custom fields. Every key/value pair from options.attributes is forwarded into User.Attributes. This is the extension point for arbitrary extra registration fields, so the module does not need to know those field names in advance.

All values inside options.attributes / User.Attributes should be sent as strings. If a field needs to contain multiple values, serialize those values into one string value, such as a comma separated list or another separator-separated list expected by the integration.

verifyEmailCode is a dedicated boolean option that controls whether User.Attributes.VERIFY_EMAIL_CODE is included in the registration payload, depending on whether email verification should be handled through an OTP code.

  • If verifyEmailCode is true, the client sends VERIFY_EMAIL_CODE: "true".
  • If verifyEmailCode is false or omitted, VERIFY_EMAIL_CODE is not sent.
await loginClient.register(
  "[email protected]",
  "ExamplePassword123!",
  "John",
  "Doe",
  {
    verifyEmailCode: true,
    attributes: {
      Specialty: "Cardiology",
      NPINumber: "1234567890",
      FullName: "John Doe",
      PracticeLegalName: "Acme Medical Group",
      CurrentTreatments: "Physical Therapy,Blood Pressure Monitoring,Insulin Therapy",
      // CurrentTreatments: "Physical Therapy | Blood Pressure Monitoring | Insulin Therapy"
    }
  }
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "TenantID": "demo-tenant",
    "Credentials": {
      "Email": "[email protected]",
      "Password": "ExamplePassword123!"
    },
    "User": {
      "FirstName": "John",
      "LastName": "Doe",
      "Email": "[email protected]",
      "Attributes": {
        "Specialty": "Cardiology",
        "NPINumber": "1234567890",
        "FullName": "John Doe",
        "PracticeLegalName": "Acme Medical Group",
        "CurrentTreatments": "Physical Therapy,Blood Pressure Monitoring,Insulin Therapy",
        "VERIFY_EMAIL_CODE": "true"
      }
    }
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Notes:

  • TenantID is taken from the configured client instance.
  • attributes is the extension point for arbitrary additional registration fields.
  • The module does not need to know custom attribute names in advance.
  • All attributes values should be strings. Multi-value attributes should be serialized into one string value, such as a comma separated list or another integration-specific separator-separated list.
  • verifyEmailCode takes precedence over any manually provided VERIFY_EMAIL_CODE inside attributes.

Verify Email

Public signature: loginClient.verifyEmail(email, code, language?, options?)

Convenience wrapper around submitOnboardingStep(...). The caller provides email, code, an optional language, and optional verification settings. VERIFY_EMAIL_CODE handling is aligned with the register(...) method behavior: when email verification should be handled through an OTP code, the client sends VERIFY_EMAIL_CODE: "true" inside User.Attributes.

  • If options.verifyEmailCode is true, the client sends VERIFY_EMAIL_CODE: "true".
  • The value is sent as a string inside User.Attributes, matching the register(...) method behavior when verifyEmailCode is true.
  • If options.verifyEmailCode is false or omitted, VERIFY_EMAIL_CODE is not sent.
  • Calling verifyEmail(...) without options keeps OTP email verification disabled by default.
await loginClient.verifyEmail(
  "[email protected]",
  "123456",
  "en",
  {
    verifyEmailCode: true
  }
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "123456",
    "Step": "EMAIL_VERIFY",
    "User": {
      "Email": "[email protected]",
      "TenantID": "demo-tenant",
      "Attributes": {
        "VERIFY_EMAIL_CODE": "true"
      }
    },
    "Language": "en"
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Resend Email Verify

Public signature: loginClient.resendEmailVerify(email, language?, options?)

Convenience wrapper around submitOnboardingStep(...). The caller provides email, an optional language, and optional verification settings. VERIFY_EMAIL_CODE handling is aligned with the register(...) method behavior: when email verification should be handled through an OTP code, the client sends VERIFY_EMAIL_CODE: "true" inside User.Attributes.

  • If options.verifyEmailCode is true, the client sends VERIFY_EMAIL_CODE: "true".
  • The value is sent as a string inside User.Attributes, matching the register(...) method behavior when verifyEmailCode is true.
  • If options.verifyEmailCode is false or omitted, VERIFY_EMAIL_CODE is not sent.
  • Calling resendEmailVerify(...) without options keeps OTP email verification disabled by default.
await loginClient.resendEmailVerify(
  "[email protected]",
  "en",
  {
    verifyEmailCode: true
  }
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "",
    "Step": "RESEND_EMAIL_VERIFY",
    "User": {
      "Email": "[email protected]",
      "TenantID": "demo-tenant",
      "Attributes": {
        "VERIFY_EMAIL_CODE": "true"
      }
    },
    "Language": "en"
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Resend SMS Verify

Public signature: loginClient.resendSmsVerify(email, phone, language?)

Convenience wrapper around submitOnboardingStep(...). The caller provides email, phone, and an optional language.

await loginClient.resendSmsVerify(
  "[email protected]",
  "+15555550123",
  "en"
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "",
    "Step": "RESEND_SMS_VERIFY",
    "User": {
      "Email": "[email protected]",
      "TenantID": "demo-tenant",
      "Phone": "+15555550123"
    },
    "Language": "en"
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Verify SMS

Public signature: loginClient.verifySms(email, phone, code, language?)

Convenience wrapper around submitOnboardingStep(...). The caller provides email, phone, code, and an optional language.

await loginClient.verifySms(
  "[email protected]",
  "+15555550123",
  "123456",
  "en"
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "123456",
    "Step": "SMS_VERIFY",
    "User": {
      "Email": "[email protected]",
      "TenantID": "demo-tenant",
      "Phone": "+15555550123"
    },
    "Language": "en"
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Save Health Profile

Public signature: loginClient.saveHealthProfile(profile, language?)

Convenience wrapper around submitOnboardingStep(...). The caller provides the SAVE_HEALTH_PROFILE input fields, such as Email, FirstName, LastName, BirthDate, Gender, Race, Ethnicity, Status, and Sex.

await loginClient.saveHealthProfile({
  Email: "[email protected]",
  FirstName: "John",
  LastName: "Doe",
  BirthDate: "1990-01-01",
  Gender: "male",
  Race: "White",
  Ethnicity: "Not Hispanic or Latino",
  Status: 0,
  Sex: "Male"
});

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "",
    "Step": "SAVE_HEALTH_PROFILE",
    "User": {
      "Email": "[email protected]",
      "TenantID": "demo-tenant",
      "FirstName": "John",
      "LastName": "Doe",
      "BirthDate": "1990-01-01",
      "Gender": "male",
      "Sex": "Male",
      "Status": 0,
      "Race": "White",
      "Ethnicity": "Not Hispanic or Latino"
    },
    "Language": "en"
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Save Address

Public signature: loginClient.saveAddress(email, address, language?)

Convenience wrapper around submitOnboardingStep(...). The caller provides email, an Address, and an optional language.

await loginClient.saveAddress("[email protected]", {
  StreetAndNumber: "123 Main St",
  Extension: null,
  City: "Springfield",
  State: "CA",
  PostalCode: "90210",
  Country: "US"
});

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "",
    "Step": "SAVE_ADDRESS",
    "User": {
      "Email": "[email protected]",
      "TenantID": "demo-tenant",
      "Address": {
        "StreetAndNumber": "123 Main St",
        "Extension": null,
        "City": "Springfield",
        "State": "CA",
        "PostalCode": "90210",
        "Country": "US"
      }
    },
    "Language": "en"
  }
}

API response

Status:

200
{
  "Data": "",
  "ErrorMessage": null,
  "IsOK": true
}

Login

Public signature: loginClient.login(email, password)

login(...) accepts only email and password. The client builds the full backend Data payload internally, and stores the returned tokens in memory. On tenants that require onboarding completion, login may depend on the relevant onboarding steps already being finished.

await loginClient.login(
  "[email protected]",
  "ExamplePassword123!"
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "FirstName": "",
    "LastName": "",
    "Email": "[email protected]",
    "Password": "ExamplePassword123!",
    "TenantID": "demo-tenant",
    "AppPoolID": "",
    "GoogleIdToken": "",
    "AppleIdToken": "",
    "AppleCode": ""
  }
}

API response

Status:

200
{
  "Data": {
    "Email": "[email protected]",
    "RefreshToken": "eyJ_refresh_token_example",
    "AccessToken": "eyJ_access_token_example",
    "IDToken": "eyJ_id_token_example",
    "EHR": "fhir",
    "HasInsurance": false,
    "HasIDCard": false,
    "HasSelfie": false,
    "Attributes": {
      "EHR": "fhir"
    },
    "TenantID": "demo-tenant",
    "Expiration": "2030-01-01T00:00:00.000Z",
    "Type": 0
  },
  "ErrorMessage": null,
  "IsOK": true
}

Reset Password

Public signature: loginClient.resetPassword(email, isPasswordResetWithOTP?)

TenantID is injected automatically from configure(...). If an ID token is already available, the client may also include an Authorization header.

await loginClient.resetPassword(
  "[email protected]",
  true
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Email": "[email protected]",
    "TenantID": "demo-tenant",
    "IsPasswordResetWithOTP": true
  }
}

Authorization: Bearer eyJ_id_token_example may also be included when an ID token is already stored.

API response

Status:

200
{
  "Data": true,
  "ErrorMessage": null,
  "IsOK": true
}

Reset Password Confirm

Public signature: loginClient.resetPasswordConfirm(email, password, code, isPasswordResetWithOTP?)

TenantID is injected automatically from configure(...). If an ID token is already available, the client may also include an Authorization header.

await loginClient.resetPasswordConfirm(
  "[email protected]",
  "ExamplePassword123!",
  "123456",
  true
);

Full API request

Request sent for the usage example above:

{
  "Data": {
    "Email": "[email protected]",
    "TenantID": "demo-tenant",
    "Password": "ExamplePassword123!",
    "code": "123456",
    "IsPasswordResetWithOTP": true
  }
}

Authorization: Bearer eyJ_id_token_example may also be included when an ID token is already stored.

API response

Status:

200
{
  "Data": true,
  "ErrorMessage": null,
  "IsOK": true
}

Refresh Token

Public signature: loginClient.refreshToken()

refreshToken() requires a successful prior login and an available refresh token. The client sends the stored refresh token, and stores the returned token set in memory.

await loginClient.refreshToken();

Full API request

Request sent for the usage example above:

{
  "Data": {
    "RefreshToken": "eyJ_refresh_token_example",
    "TenantID": "demo-tenant"
  }
}

API response

Status:

200
{
  "Data": {
    "Email": null,
    "RefreshToken": "eyJ_refresh_token_example",
    "AccessToken": "eyJ_access_token_example",
    "IDToken": "eyJ_id_token_example",
    "TenantID": "demo-tenant",
    "Expiration": "2030-01-01T00:00:00.000Z",
    "Type": 0
  },
  "ErrorMessage": null,
  "IsOK": true
}

Get Auth Header

Public signature: loginClient.getAuthHeader()

Returns the authorization headers required for authenticated API requests. This method does not send an HTTP request, and other Healthcheck connectors can reuse the returned header object directly.

const headers = loginClient.getAuthHeader();

Full API request

getAuthHeader() does not send an HTTP request. The usage example above reads the value from local state.

API response

getAuthHeader() returns the current local header object.

{
  "Authorization": "Bearer eyJ_id_token_example",
  "X-Tenant-ID": "demo-tenant"
}

Get User Info

Public signature: loginClient.getUserInfo()

The current implementation calls the patient header endpoint and returns the raw server response. It requires a stored ID token, and it currently targets the same endpoint as getHeader().

const userInfo = await loginClient.getUserInfo();

Full API request

getUserInfo() does not send a request body.

API response

Status:

200
{
  "Data": {
    "Record": {
      "ID": "record-id-example",
      "TenantID": "demo-tenant",
      "FirstName": "John",
      "LastName": "Doe",
      "Email": "[email protected]",
      "Phone": "+15555550123",
      "BirthDate": "1990-01-01T00:00:00",
      "Gender": "male",
      "Sex": "Male",
      "Race": "White",
      "Ethnicity": "Not Hispanic or Latino",
      "HasInsurance": false,
      "HasIDCard": false,
      "HasSelfie": false,
      "Address": {
        "StreetAndNumber": "123 Main St",
        "Extension": null,
        "City": "Springfield",
        "State": "CA",
        "PostalCode": "90210",
        "Country": "US"
      },
      "Attributes": {
        "FHIRPatientID": "patient-id-example",
        "CompositeID": "composite-id-example",
        "VERIFY_EMAIL_CODE": "true"
      },
      "CompositeID": "composite-id-example",
      "FHIRID": "fhir-id-example"
    },
    "Encounters": null,
    "EHR": "fhir",
    "PendingActions": [
      "ADD_INSURANCE",
      "ADD_ID",
      "IMPORT_VITALS"
    ]
  },
  "ErrorMessage": null,
  "IsOK": true
}

Get Header

Public signature: loginClient.getHeader()

The current implementation also calls the patient header endpoint. It requires a stored ID token, and the response shape is effectively the same as getUserInfo().

await loginClient.getHeader();

Full API request

getHeader() does not send a request body.

API response

Status:

200
{
  "Data": {
    "Record": {
      "ID": "record-id-example",
      "TenantID": "demo-tenant",
      "FirstName": "John",
      "LastName": "Doe",
      "Email": "[email protected]",
      "Phone": "+15555550123",
      "BirthDate": "1990-01-01T00:00:00",
      "Gender": "male",
      "Sex": "Male",
      "Race": "White",
      "Ethnicity": "Not Hispanic or Latino",
      "HasInsurance": false,
      "HasIDCard": false,
      "HasSelfie": false,
      "Address": {
        "StreetAndNumber": "123 Main St",
        "Extension": null,
        "City": "Springfield",
        "State": "CA",
        "PostalCode": "90210",
        "Country": "US"
      },
      "Attributes": {
        "FHIRPatientID": "patient-id-example",
        "CompositeID": "composite-id-example",
        "VERIFY_EMAIL_CODE": "true"
      },
      "CompositeID": "composite-id-example",
      "FHIRID": "fhir-id-example"
    },
    "Encounters": null,
    "EHR": "fhir",
    "PendingActions": [
      "ADD_INSURANCE",
      "ADD_ID",
      "IMPORT_VITALS"
    ]
  },
  "ErrorMessage": null,
  "IsOK": true
}

Get Access Token

Public signature: loginClient.getAccessToken()

Returns the current in-memory access token.

const accessToken = loginClient.getAccessToken();

Full API request

getAccessToken() does not send an HTTP request. The usage example above reads the value from local state.

API response

getAccessToken() returns the current local access token value.

eyJ_access_token_example

Get ID Token

Public signature: loginClient.getIDToken()

Returns the current in-memory ID token.

const idToken = loginClient.getIDToken();

Full API request

getIDToken() does not send an HTTP request. The usage example above reads the value from local state.

API response

getIDToken() returns the current local ID token value.

eyJ_id_token_example

How It Works

  • Create a shared HttpClient instance and a single HCLoginClient.
  • Call configure(...) once to store tenant and environment settings locally.
  • Call register(...) if the patient account needs to be created.
  • Use submitOnboardingStep(...) or the onboarding helper methods to complete required onboarding steps.
  • Call login(...) to authenticate and store the returned access, refresh, and ID tokens in memory.
  • Use refreshToken() to replace the current token set when needed.
  • Use getAuthHeader(), getAccessToken(), getIDToken(), getUserInfo(), and getHeader() for authenticated flows after login.
  • Other Healthcheck connectors can consume getAuthHeader() instead of managing auth tokens directly.

Notes

  • configure() stores tenant configuration locally and does not send an HTTP request.
  • TenantID is injected by the client into tenant-bound register, onboarding, login, refresh, and password requests.
  • register(), verifyEmail(), and resendEmailVerify() all follow the same string-based User.Attributes.VERIFY_EMAIL_CODE pattern for OTP email verification flows.
  • saveAddress() accepts an Address.
  • login() and refreshToken() both store returned tokens internally for later helper calls.
  • getUserInfo() and getHeader() both currently call the patient header endpoint.
  • getAuthHeader(), getAccessToken(), getIDToken(), getBaseUrl(), and getTenantId() return local values and do not perform HTTP requests.
  • This connector is intended to be reused by other Healthcheck SDK connectors built on the same HTTP layer.