Skip to content
Last updated

Connections

A Hypersync connection is an object stored in Hyperproof that contains the credentials and configuration needed to connect to an external service’s API. Each connection must comply with that service’s authentication and authorization requirements.

External services use various authentication methods:

  • Basic auth (email and password)
  • API keys (included in request headers)
  • OAuth 2.0 (requires an access token per request)
  • Databases like SQL Server and MySQL (typically require a username and password)

In a Hypersync app, there are two connection types: OAuth connections and custom authentication connections.

Note: The OAuth references in this article refer to the OAuth 2.0 authorization code flow. In the authorization code flow, the service redirects the user’s browser to its authorization server, where the user signs in. After signing in, the user is presented with a consent screen to explicitly grant access to their data. Once consent is granted, the service redirects back to your application with an authorization code, which your app can then exchange for an access token.

Tip: For services that use OAuth 2.0's client credentials flow, a custom authentication connection should be used.

Note: Always use the minimum permissions necessary for proof. Hypersyncs are read-only, so use read-only permissions when possible. Further, use minimum scopes when using OAuth. During authorization, the Hypersync author is prompted to grant access to the specified scopes, so it’s best practice to request only what your app actually needs.

OAuth authorization

For services that use OAuth 2.0 for authorization, the Hypersync SDK provides built-in functionality to obtain and manage the access tokens required by those APIs.

In this flow, the end user authorizes Hyperproof to perform specific operations on their behalf. Behind the scenes, Hyperproof exchanges that authorization for an access token, which is then used to make authenticated API calls. The user only needs to complete the authorization flow once.

To configure a Hypersync app for OAuth authorization, set authType to oauth in your package.json. See the Custom Hypersync app package.json article for more details.

Next, make sure you have a .env file at the root of your project with the following values:

oauth_authorization_url=https://YOUR_EXTERNAL_SERVICE/oauth/v2/auth
oauth_token_url=https://YOUR_EXTERNAL_SERVICE/oauth/v2/token
oauth_scope=obj1.read obj1.update obj2.read obj2.update
oauth_extra_params=
oauth_client_id=YOUR_CLIENT_ID
oauth_client_secret=YOUR_CLIENT_SECRET

Note: In the Hypersync SDK Samples repository, all OAuth sample apps include a .env.template file that you can copy to .env and then customize for your needs.

Once you've configured your .env file, implement the getUserProfle method on your HypersyncApp class. This method returns an object containing information about the authorizing user.

 interface IMyServiceUser {
    userId: string;
    firstName: string;
    lastName: string;
  }

  async getUserProfile(tokenContext: OAuthTokenResponse) {
    const dataSource = new MyServiceDataSource(tokenContext.access_token);
    const serviceUser = await dataSource.getDataObject('currentUser');
    const userProfile: IMyServiceUser = {
      userId: serviceUser.id
      firstName: serviceUser.givenName,
      lastName: serviceUser.surname
    };
    return userProfile;
  }

Finally, implement the getUserId and getUserAccountName methods. getUserId is used to uniquely identify the user within the external service. getUserAccountName returns a friendly name for the connection. This value is shown in Settings > Connected accounts in Hyperproof.

Important: The user ID must be unique to the authorizing user!

  public async getUserId(userProfile: IMyServiceUser) {
    return userProfile.userId;
  }

  /**
   * Returns a human readable string which identifies the user's account.
   * This string is displayed in Hyperproof's Connected Accounts page to help the
   * user distinguish between multiple connections that use different accounts.
   *
   * @param userProfile The profile of the user returned by getUserProfile.
   */
  public getUserAccountName(userProfile: IMyServiceUser) {
    return `${userProfile.firstName} ${userProfile.lastName}`;
  }

Custom authentication

All non-OAuth authentication/authorization schemes are classified as "custom" in the Hyperysnc SDK. If your service does not use OAuth 2.0, you should specify custom as your authType in package.json. See the Custom Hypersync app package.json article for more details.

Custom auth covers any type of authentication where the user provides credentials to make a connection. Credentials can include user username/password, access key/secret key, API Token, and many others. Users may also need to designate the endpoint they’re connecting to, e.g. by providing a URL or a region.

Step One

Your app's HypersyncApp class must be modified to support custom authentication. Begin by updating the credentialsMetadata field in the constructor:

  constructor() {
    super({
      appRootDir: __dirname,
      connectorName: 'My Service Connector',
      messages: Messages,
      credentialsMetadata: {
        instructionHeader: 'Please enter your My Service credentials',
        fields: [
          {
            name: 'username',
            type: CredentialFieldType.TEXT,
            label: 'User Name'
          },
          {
            name: 'password',
            type: CredentialFieldType.PASSWORD,
            label: 'Password'
          }
        ]
      }
    });
  }

The instruction header, along with each of the fields, is shown to the user when they attempt to create a connection to your service.

Step Two

Next, implement the validateCredentials method. This method is called by Hyperproof as soon as the user provides the credentials and clicks Next.

  interface IMyServiceUser {
    firstName: string;
    lastName: string;
  }

  public async validateCredentials(
    credentials: CustomAuthCredentials
  ): Promise<IValidatedUser<IMyServiceUser>> {
    try {
      // Get the username and password provided by the user.
      const { username, password } = credentials as {
        [key: string]: string;
      };

      // TODO: Connect to My Service and validate credentials.  Then
      // retrieve identifying information for the user (e.g. through
      // some sort of /users/me route).
      const userDetails = ...

      return {
        userId: username as string,
        profile: {
          firstName: userDetails.givenName,
          lastName: userDetails.surname
        }
      };
    } catch (err) {
      Logger.debug('My Service credentials validation failed.');
      Logger.debug(err);
      throw createHttpError(
        StatusCodes.UNAUTHORIZED,
        'Invalid Credentials'
      );
    }
  }

Step Three

Finally, implement the getAccountName method which returns a friendly name for the connection. This value is shown in Settings > Connected accounts in Hyperproof.

  public getUserAccountName(userProfile: IMyServiceUser) {
    return `${userProfile.firstName} ${userProfile.lastName}`;
  }