npm.io
0.4.1 • Published 2d ago

@healthcloudai/hc-login-connector

Licence
MIT
Version
0.4.1
Deps
2
Size
81 kB
Vulns
0
Weekly
404

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 stored refresh token
  9. Authenticated patient header retrieval through getPatientHeader()
  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("test-tenant", "dev");
// The current source signature also accepts an optional region argument:
// loginClient.configure("test-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.


API Key

Use setApiKey(...) to include an API key header with requests made by HCLoginClient.

const apiKey = process.env.HEALTHCLOUD_API_KEY;

if (!apiKey) {
  throw new Error("HEALTHCLOUD_API_KEY is required.");
}

loginClient.setApiKey("x-api-key", apiKey);

The first argument is the header name and the second argument is the API key value. After it is configured, the API key header is included automatically with registration, onboarding, login, token refresh, password reset, and authenticated patient header requests.

If your environment does not require an API key, you can skip this step.

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

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.

test-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: "john.smith@example.com",
    FirstName: "John",
    LastName: "Smith",
    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": "john.smith@example.com",
      "TenantID": "test-tenant",
      "FirstName": "John",
      "LastName": "Smith",
      "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.

isOTP 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 isOTP is true, the client sends VERIFY_EMAIL_CODE: "true".
  • If isOTP is false or omitted, VERIFY_EMAIL_CODE is not sent.
OTP-based registration

Use this when email verification should be handled through an OTP code. In this case, isOTP should be true.

await loginClient.register(
  "john.smith@example.com",
  "ExamplePassword123!",
  "John",
  "Smith",
  {
    isOTP: true,
    attributes: {
      "ReferralSource": "Friend"
    }
  }
);
Full API request

Request sent for the OTP example above:

{
  "Data": {
    "TenantID": "test-tenant",
    "Credentials": {
      "Email": "john.smith@example.com",
      "Password": "ExamplePassword123!"
    },
    "User": {
      "FirstName": "John",
      "LastName": "Smith",
      "Email": "john.smith@example.com",
       "Attributes": {
        "VERIFY_EMAIL_CODE": "true",
        "ReferralSource": "Friend"
      }
    }
  }
}

Use this when email verification should be handled through an email link. In this case, isOTP should be omitted or false.

await loginClient.register(
  "john.smith@example.com",
  "ExamplePassword123!",
  "John",
  "Smith"
);

Effective request body:

{
  "Data": {
    "TenantID": "test-tenant",
    "Credentials": {
      "Email": "john.smith@example.com",
      "Password": "ExamplePassword123!"
    },
    "User": {
      "FirstName": "John",
      "LastName": "Smith",
      "Email": "john.smith@example.com",
      "Attributes": {}
    }
  }
}
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.
  • isOTP takes precedence over any manually provided VERIFY_EMAIL_CODE inside attributes.

Register Full

Public signature: loginClient.registerFull(options?)

Registers a patient for the configured tenant using the richer registration payload.

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

isOTP behaves the same way as in register(...): when enabled, the client injects VERIFY_EMAIL_CODE: "true" into User.Attributes.

OTP-based registration

Use this when email verification should be handled through an OTP code. In this case, isOTP should be true.

await loginClient.registerFull({
  email: "john.smith@example.com",
  password: "ExamplePassword123!",
  firstName: "John",
  lastName: "Smith",
  phone: "+15555550123",
  birthDate: "1990-01-01",
  gender: "Male",
  middleName: "Test",
  race: "Other",
  ethnicity: "Other",
  sex: "Male",
  genderIdentity: "Male",
  status: 0,
  language: "en",
  isOTP: true,
  attributes: {
    source: "sdk-test"
  },
  address: {
    StreetAndNumber: "123 Test St",
    Extension: "Apt 4",
    City: "Springfield",
    State: "CA",
    PostalCode: "90210",
    Country: "US"
  }
});
Full API request

Request sent for the usage example above:

{
  "Data": {
    "TenantID": "test-tenant",
    "Credentials": {
      "Email": "john.smith@example.com",
      "Password": "ExamplePassword123!",
      "TenantID": "test-tenant",
      "Language": "en"
    },
    "User": {
      "FirstName": "John",
      "LastName": "Smith",
      "Email": "john.smith@example.com",
      "Phone": "+15555550123",
      "BirthDate": "1990-01-01",
      "Gender": "Male",
      "MiddleName": "Test",
      "Race": "Other",
      "Ethnicity": "Other",
      "Sex": "Male",
      "GenderIdentity": "Male",
      "Status": 0,
      "Address": {
        "StreetAndNumber": "123 Test St",
        "Extension": "Apt 4",
        "City": "Springfield",
        "State": "CA",
        "PostalCode": "90210",
        "Country": "US"
      },
      "Attributes": {
        "source": "sdk-test",
        "VERIFY_EMAIL_CODE": "true"
      }
    }
  }
}

Use this when email verification should be handled through an email link. In this case, isOTP should be omitted or false.

await loginClient.registerFull({
  email: "john.smith@example.com",
  password: "ExamplePassword123!",
  firstName: "John",
  lastName: "Smith"
});

Effective request body:

{
  "Data": {
    "TenantID": "test-tenant",
    "Credentials": {
      "Email": "john.smith@example.com",
      "Password": "ExamplePassword123!",
      "TenantID": "test-tenant"
    },
    "User": {
      "FirstName": "John",
      "LastName": "Smith",
      "Email": "john.smith@example.com",
      "Attributes": {}
    }
  }
}
API response

Status:

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

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.isOTP 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 isOTP is true.
  • If options.isOTP is false or omitted, VERIFY_EMAIL_CODE is not sent.
  • Calling verifyEmail(...) without options keeps OTP email verification disabled by default.
OTP-based email verification

Use this when email verification should be handled through an OTP code. In this case, options.isOTP should be true.

await loginClient.verifyEmail(
  "john.smith@example.com",
  "123456",
  "en",
  {
    isOTP: true
  }
);
Full API request

Request sent for the OTP example above:

{
  "Data": {
    "Data": "123456",
    "Step": "EMAIL_VERIFY",
    "User": {
      "Email": "john.smith@example.com",
      "TenantID": "test-tenant",
      "Attributes": {
        "VERIFY_EMAIL_CODE": "true"
      }
    },
    "Language": "en"
  }
}

Use this when email verification should be handled through an email link. In this case, options.isOTP should be omitted or false.

await loginClient.verifyEmail(
  "john.smith@example.com",
  "123456",
  "en"
);

Effective request body:

{
  "Data": {
    "Data": "123456",
    "Step": "EMAIL_VERIFY",
    "User": {
      "Email": "john.smith@example.com",
      "TenantID": "test-tenant"
    },
    "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.isOTP 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 isOTP is true.
  • If options.isOTP is false or omitted, VERIFY_EMAIL_CODE is not sent.
  • Calling resendEmailVerify(...) without options keeps OTP email verification disabled by default.
OTP-based resend

Use this when email verification should be handled through an OTP code. In this case, options.isOTP should be true.

await loginClient.resendEmailVerify(
  "john.smith@example.com",
  "en",
  {
    isOTP: true
  }
);
Full API request

Request sent for the OTP example above:

{
  "Data": {
    "Data": "",
    "Step": "RESEND_EMAIL_VERIFY",
    "User": {
      "Email": "john.smith@example.com",
      "TenantID": "test-tenant",
      "Attributes": {
        "VERIFY_EMAIL_CODE": "true"
      }
    },
    "Language": "en"
  }
}

Use this when email verification should be handled through an email link. In this case, options.isOTP should be omitted or false.

await loginClient.resendEmailVerify(
  "john.smith@example.com",
  "en"
);

Effective request body:

{
  "Data": {
    "Data": "",
    "Step": "RESEND_EMAIL_VERIFY",
    "User": {
      "Email": "john.smith@example.com",
      "TenantID": "test-tenant"
    },
    "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(
  "john.smith@example.com",
  "+15555550123",
  "en"
);
Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "",
    "Step": "RESEND_SMS_VERIFY",
    "User": {
      "Email": "john.smith@example.com",
      "TenantID": "test-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(
  "john.smith@example.com",
  "+15555550123",
  "123456",
  "en"
);
Full API request

Request sent for the usage example above:

{
  "Data": {
    "Data": "123456",
    "Step": "SMS_VERIFY",
    "User": {
      "Email": "john.smith@example.com",
      "TenantID": "test-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: "john.smith@example.com",
  FirstName: "John",
  LastName: "Smith",
  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": "john.smith@example.com",
      "TenantID": "test-tenant",
      "FirstName": "John",
      "LastName": "Smith",
      "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("john.smith@example.com", {
  StreetAndNumber: "123 Test 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": "john.smith@example.com",
      "TenantID": "test-tenant",
      "Address": {
        "StreetAndNumber": "123 Test 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 login 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(
  "john.smith@example.com",
  "ExamplePassword123!"
);
Full API request

Request sent for the full payload usage example above:

{
  "Data": {
    "Email": "john.smith@example.com",
    "Password": "ExamplePassword123!",
    "TenantID": "test-tenant"
  }
}
API response

Status:

200
{
  "Data": {
    "Email": "john.smith@example.com",
    "RefreshToken": "eyJ_refresh_token_example",
    "AccessToken": "eyJ_access_token_example",
    "IDToken": "eyJ_id_token_example",
    "EHR": "fhir",
    "ErrorMessage": null,
    "HasInsurance": false,
    "HasIDCard": false,
    "HasSelfie": false,
    "Attributes": {
      "EHR": "fhir",
      "Type": "PATIENT"
    },
    "ID": "john.smith@example.com",
    "TenantID": "test-tenant",
    "Expiration": "2030-01-01T00:00:00.000Z",
    "Type": 0
  },
  "ErrorMessage": null,
  "IsOK": true
}

Reset Password

requestPasswordReset supports both OTP-based and link-based reset initiation flows.

isOTP is optional. When it is true, the client includes IsPasswordResetWithOTP: true in the API request. When false or omitted, the backend field is not sent at all.

OTP-based password reset initiation

Use this when the password reset flow should be handled through an OTP code. In this case, isOTP should be true.

await loginClient.requestPasswordReset("john.smith@example.com", true);
Full API request
{
  "Data": {
    "Email": "john.smith@example.com",
    "TenantID": "test-tenant",
    "IsPasswordResetWithOTP": true
  }
}

Use this when the password reset flow should be handled from an email link. In this case, isOTP should be omitted by passing false or leaving the second argument out.

await loginClient.requestPasswordReset("john.smith@example.com", false);

Effective request body:

{
  "Data": {
    "Email": "john.smith@example.com",
    "TenantID": "test-tenant"
  }
}

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

confirmPasswordReset supports both OTP-based and link-based confirmation flows.

If isOTP is true, Code is required. If isOTP is not true, Token is required. The client maps isOTP: true to IsPasswordResetWithOTP: true in the API request. For the link-based flow, the frontend is responsible for taking the token from the password reset email link and passing that token in the payload.

OTP-based password reset confirmation

Use this when the password reset flow was started with OTP. In this case, isOTP should be true and Code should contain the final reset code.

await loginClient.confirmPasswordReset({
  Email: "john.smith@example.com",
  Password: "ExamplePassword123!",
  isOTP: true,
  Code: "123456"
});

Request body:

{
  "Data": {
    "Email": "john.smith@example.com",
    "TenantID": "test-tenant",
    "Password": "ExamplePassword123!",
    "Code": "123456",
    "IsPasswordResetWithOTP": true
  }
}

Use this when the password reset flow was started from an email link. In this case, Token should be included in the payload, the frontend should read the token value from the password reset email link and send that token in the request payload, and isOTP should be omitted or false.

await loginClient.confirmPasswordReset({
  Email: "john.smith@example.com",
  Password: "ExamplePassword123!",
  Token: "token-from-email-link"
});

Effective request body:

{
  "Data": {
    "Email": "john.smith@example.com",
    "TenantID": "test-tenant",
    "Password": "ExamplePassword123!",
    "Token": "token-from-email-link"
  }
}

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 previous successful login and a stored 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": "test-tenant"
  }
}
API response

Status:

200
{
  "Data": {
    "Email": null,
    "RefreshToken": "eyJ_refresh_token_example",
    "AccessToken": "eyJ_access_token_example",
    "IDToken": "eyJ_id_token_example",
    "EHR": null,
    "ErrorMessage": null,
    "HasInsurance": false,
    "HasIDCard": false,
    "HasSelfie": false,
    "Attributes": null,
    "ID": null,
    "TenantID": "test-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": "test-tenant"
}

If an API key has been configured through setApiKey(...), the returned header object also includes the configured API key header.


Get Patient Header

Public signature: loginClient.getPatientHeader()

Calls the patient header endpoint and returns the raw server response. It requires a stored ID token.

const header = await loginClient.getPatientHeader();
Full API request

getPatientHeader() does not send a request body.

API response

Status:

200
{
  "Data": {
    "Record": {
      "Status": 1,
      "Sex": "Male",
      "GenderIdentity": "Male",
      "HasInsurance": true,
      "HasIDCard": true,
      "HasSelfie": true,
      "Flags": null,
      "FirstName": "John",
      "LastName": "Smith",
      "MiddleName": null,
      "BirthDate": "1990-01-01T00:00:00",
      "Email": "john.smith@example.com",
      "Phone": "+15555550123",
      "Gender": "Male",
      "Race": "White",
      "Ethnicity": "",
      "CRMID": null,
      "AppleUserId": null,
      "Address": {
        "StreetAndNumber": "1 Main St",
        "Extension": null,
        "City": "Springfield",
        "State": "IL",
        "PostalCode": "62701",
        "Country": "US"
      },
      "Attributes": {
        "AthenaPatientID": "patient-id-example",
        "AthenaGuarantorFirstName": "John",
        "AthenaGuarantorLastName": "Smith",
        "AthenaGuarantorEmail": "john.smith@example.com",
        "AthenaCountryCode": "USA",
        "AthenaDepartmentId": "1",
        "AthenaEmailExists": "True",
        "AthenaTestPatient": "False",
        "PatientImageURL": "https://storage.example.com/selfie_example.jpg",
        "CompositeID": "tenant-id/john.smith@example.com",
        "Insurance": "EXAMPLE INSURANCE"
      },
      "CompositeID": "tenant-id/john.smith@example.com",
      "FHIRID": "fhir-id-example",
      "AthenaID": "patient-id-example",
      "Created": "0001-01-01T00:00:00",
      "Modified": "0001-01-01T00:00:00",
      "CreatedByID": null,
      "ModifiedByID": null,
      "IsDeactivated": false,
      "TenantID": "test-tenant",
      "ID": "record-uuid-example"
    },
    "Encounters": null,
    "EHR": "athena",
    "PendingActions": [
      "TAKE_TEST"
    ]
  },
  "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 a stored refresh token is available.
  • Use getAuthHeader(), getAccessToken(), getIDToken(), and getPatientHeader() for authenticated flows after login.
  • Other Healthcheck connectors can consume getAuthHeader() instead of managing auth tokens directly.

Token Expiry and Refresh

The SDK does not auto-refresh tokens. Call refreshToken() proactively when the token is about to expire.

getTokens() returns the current in-memory token set, including expiresAt — an absolute Unix millisecond timestamp parsed from the Expiration field the backend returns.

isTokenExpired() is a helper that returns true when there is no stored token or when Date.now() >= expiresAt.

Recommended pattern:

async function ensureFreshToken(loginClient: HCLoginClient): Promise<void> {
  if (loginClient.isTokenExpired()) {
    await loginClient.refreshToken();
  }
}

// Call before any authenticated connector operation
await ensureFreshToken(loginClient);
const result = await otherConnector.someMethod();

getTokens() shape:

interface AuthTokens {
  accessToken: string;
  refreshToken: string;
  idToken: string | null;
  expiresAt: number; // absolute milliseconds since Unix epoch
}

refreshToken() does not require a current ID token. It uses the stored refresh token from the previous successful login() call.


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() stores the initial token set internally, and refreshToken() updates that stored token set when a refresh token is available.
  • getPatientHeader() calls the patient header endpoint.
  • getAuthHeader() returns Authorization: Bearer <idToken> + X-Tenant-ID. It does not carry an API key — each connector adds its own key independently.
  • getAuthHeader(), getAccessToken(), getIDToken(), getBaseUrl(), getTenantId(), getTokens(), and isTokenExpired() return or evaluate 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.

getPatientHeader vs getDashboard

HCLoginClient.getPatientHeader() calls /api/patient/header and returns a lightweight patient record plus pending actions. Typically called once after login to check patient state.

HCSettingsClient.getDashboard() (in hc-settings-connector) calls /api/patient/dashboard and returns a richer dashboard including encounters. These are different endpoints with different response shapes — not duplicates.

Keywords