Skip to content

Commit

Permalink
API v3.1 additions, changes base URLs, adds tests, bumps version… (#37)
Browse files Browse the repository at this point in the history
* Update to use API v3.1 and add new features
* Make region required and change base URL for EU region
* Bump version to 2.0.0
* Convert autofill address lines to camelCase

Co-authored-by: Ciaran Lawlor <[email protected]>
  • Loading branch information
Ben Ahmady and ciaran16 authored Apr 14, 2021
1 parent 06210c9 commit 55490e0
Show file tree
Hide file tree
Showing 23 changed files with 173 additions and 147 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12
15
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nodejs 12.13.0
nodejs 15.7.0
19 changes: 10 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
# Changelog

## v2.0.0, 9 April 2021

- Updated to use API v3.1
- Region is now a required argument when constructing an `Onfido` instance. The region previously defaulted to `Region.EU`
- Add support for downloading a check

## v1.6.0, 8 March 2021

- Add `privacy_notices_read_consent_given` to the type for creating a chec

## v1.5.4, 12 January 2021

- Updated dependencies.


## v1.5.3, 3 December 2020

- Library should work now with `esModuleInterop: false`


## v1.5.2, 3 September 2020

- Fix type declaration location for TypeScript users


## v1.5.1, 20 August 2020

- Ensure consistent version in User-Agent


## v1.5.0, 14 August 2020

- Add User Agent header


## v1.4.0, 15 July 2020

- Add support for [Autofill endpoint](https://documentation.onfido.com/#autofill-beta)


## v1.3.0, 30 June 2020

- Add support for `cross_device_url` when generating an SDK token


## v1.2.0, 23 June 2020

- Allow specifying the filepath and content type explicitly for file upload
- Add support for the Canada region (api.ca.onfido.com)
- Add missing `document_ids` field to `CheckRequest` type


## v1.1.0, 2 April 2020

- Improved typing of check and report objects.


## v1.0.0, 23 January 2020

- The initial release of this library, which uses v3 of the Onfido API
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Documentation can be found at <https://documentation.onfido.com>

This library is only for use on the backend, as it uses Onfido API tokens which must be kept secret. If you do need to collect applicant data in the frontend of your application, we recommend that you use one of [the Onfido SDKs](https://developers.onfido.com/sdks/).

This version uses Onfido API v3.1. Refer to our [API versioning guide](https://developers.onfido.com/guide/api-versioning-policy#client-libraries) for details of which client library versions use which versions of the API.

## Installation

For npm:
Expand Down Expand Up @@ -34,13 +36,13 @@ For TypeScript users, types are available as well:
import { Onfido, Region, Applicant, OnfidoApiError } from "@onfido/api";
```

Configure with your API token, and region if necessary:
Configure with your API token and region:

```js
const onfido = new Onfido({
apiToken: process.env.ONFIDO_API_TOKEN
// Defaults to Region.EU (api.onfido.com), supports Region.US and Region.CA
// region: Region.US
apiToken: process.env.ONFIDO_API_TOKEN,
// Supports Region.EU, Region.US and Region.CA
region: Region.EU
});
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onfido/api",
"version": "1.6.0",
"version": "2.0.0",
"description": "Node.js library for the Onfido API",
"keywords": [
"onfido",
Expand Down
22 changes: 10 additions & 12 deletions src/Onfido.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,11 @@ export enum Region {

export type OnfidoOptions = {
apiToken: string;
region?: Region;
region: Region;
timeout?: number;
unknownApiUrl?: string;
};

const apiUrls = {
[Region.EU]: "https://api.onfido.com/v3/",
[Region.US]: "https://api.us.onfido.com/v3/",
[Region.CA]: "https://api.ca.onfido.com/v3/"
};

export class Onfido {
public readonly axiosInstance: AxiosInstance;
// Core resources
Expand All @@ -47,19 +41,23 @@ export class Onfido {

constructor({
apiToken,
region = Region.EU,
region,
timeout = 30_000,
unknownApiUrl
}: OnfidoOptions) {
if (!apiToken) {
throw new Error("No apiToken provided");
}

const regionUrl = apiUrls[region];
if (!regionUrl) {
throw new Error("Unknown region " + region);
if (!region || !Object.values(Region).includes(region)) {
throw new Error(
`Unknown or missing region '${region}'. ` +
"We previously defaulted to region 'EU', so if you previously didn’t " +
"set a region or used api.onfido.com, please set your region to 'EU'"
);
}

const regionUrl = `https://api.${region.toLowerCase()}.onfido.com/v3.1/`;

this.axiosInstance = axios.create({
baseURL: unknownApiUrl || regionUrl,
headers: {
Expand Down
10 changes: 6 additions & 4 deletions src/formatting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ type ContentsAndOptions = {

export type FileLike = Readable | ContentsAndOptions;

const snakeCase = (s: string): string =>
s.replace(/[A-Z]/g, char => `_${char.toLowerCase()}`);
const snakeCase = (camelCaseString: string): string =>
camelCaseString.replace(/[A-Z]/g, char => `_${char.toLowerCase()}`);

const camelCase = (s: string): string =>
s.replace(/_[a-z]/g, underscoreChar => underscoreChar[1].toUpperCase());
const camelCase = (snakeCaseString: string): string =>
snakeCaseString
.replace(/_[0-9]/g, underscoreDigit => underscoreDigit[1])
.replace(/_[a-z]/g, underscoreChar => underscoreChar[1].toUpperCase());

const deepMapObjectKeys = (value: unknown, f: (key: string) => string): any => {
if (!(value instanceof Object)) {
Expand Down
8 changes: 8 additions & 0 deletions src/resources/Checks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AxiosInstance } from "axios";
import { OnfidoDownload } from "../OnfidoDownload";
import { Method, Resource } from "../Resource";

export type CheckRequest = {
Expand All @@ -11,6 +12,7 @@ export type CheckRequest = {
suppressFormEmails?: boolean;
redirectUri?: string | null;
privacyNoticesReadConsentGiven?: boolean;
webhookIds?: string[] | null;
};

export type Check = {
Expand All @@ -26,6 +28,8 @@ export type Check = {
formUri: string | null;
redirectUri: string | null;
resultsUri: string;
privacyNoticesReadConsentGiven: boolean;
webhookIds: string[] | null;
};

export class Checks extends Resource<CheckRequest> {
Expand Down Expand Up @@ -53,4 +57,8 @@ export class Checks extends Resource<CheckRequest> {
public async resume(id: string): Promise<void> {
await this.request({ method: Method.POST, path: `${id}/resume` });
}

public async download(id: string): Promise<OnfidoDownload> {
return super.download(`${id}/download`);
}
}
29 changes: 20 additions & 9 deletions test/Onfido.test.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,49 @@
import { Onfido, Region } from "onfido-node";

it("sets the authorization header from the given token", () => {
const onfido = new Onfido({ apiToken: "api_token" });
const onfido = new Onfido({ apiToken: "api_token", region: Region.EU });
expect(onfido.axiosInstance.defaults.headers.Authorization).toBe(
"Token token=api_token"
);
});

it("contains a user agent header", () => {
const onfido = new Onfido({ apiToken: "api_token" });
const onfido = new Onfido({ apiToken: "api_token", region: Region.EU });
expect(onfido.axiosInstance.defaults.headers["User-Agent"]).toMatch(
/^onfido-node\/\d+\.\d+\.\d+$/
);
});

it("defaults to the EU region", () => {
const onfido = new Onfido({ apiToken: "token" });
it("allows setting the EU region", () => {
const onfido = new Onfido({ apiToken: "token", region: Region.EU });
expect(onfido.axiosInstance.defaults.baseURL).toBe(
"https://api.onfido.com/v3/"
"https://api.eu.onfido.com/v3.1/"
);
});

it("allows setting the US region", () => {
const onfido = new Onfido({ apiToken: "token", region: Region.US });
expect(onfido.axiosInstance.defaults.baseURL).toBe(
"https://api.us.onfido.com/v3/"
"https://api.us.onfido.com/v3.1/"
);
});

it("allows setting the CA region", () => {
const onfido = new Onfido({ apiToken: "token", region: Region.CA });
expect(onfido.axiosInstance.defaults.baseURL).toBe(
"https://api.ca.onfido.com/v3/"
"https://api.ca.onfido.com/v3.1/"
);
});

it("throws an error for no region", () => {
expect(() => new Onfido({ apiToken: "token" } as any)).toThrow(
"Unknown or missing region 'undefined'"
);
});

it("throws an error for unknown regions", () => {
expect(() => new Onfido({ apiToken: "token", region: "abc" as any })).toThrow(
"Unknown region abc"
"Unknown or missing region 'abc'"
);
});

Expand All @@ -47,6 +53,11 @@ it("throws an error if no api token is provided", () => {
});

it("allows changing the default timeout", () => {
const onfido = new Onfido({ apiToken: "token", timeout: 123 });
const onfido = new Onfido({
apiToken: "token",
region: Region.EU,
timeout: 123
});

expect(onfido.axiosInstance.defaults.timeout).toBe(123);
});
13 changes: 4 additions & 9 deletions test/Resource.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import axios from "axios";
import nock from "nock";
import { OnfidoApiError, OnfidoDownload } from "onfido-node";
import { Resource } from "../src/Resource";

const axiosInstance = axios.create({
baseURL: "https://api.onfido.com/v3/"
});
import { createNock, onfido } from "./testHelpers";

class TestResource extends Resource<{}> {
public constructor() {
super("test", axiosInstance);
super("test", onfido.axiosInstance);
}

public async upload(body: {}): Promise<any> {
Expand Down Expand Up @@ -37,7 +32,7 @@ describe("error handling", () => {
it("returns an OnfidoApiError when a response is recieved", async () => {
expect.assertions(2);

nock("https://api.onfido.com/v3")
createNock()
.post("/test/")
.reply(404, "Not Found");

Expand All @@ -52,7 +47,7 @@ describe("error handling", () => {
it("reads json error messages when streaming the response", async () => {
expect.assertions(2);

nock("https://api.onfido.com/v3")
createNock()
.get("/test/123/download")
.reply(400, errorJson);

Expand Down
4 changes: 2 additions & 2 deletions test/formatting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ describe("convertObjectToCamelCase", () => {
expect(
convertObjectToCamelCase({
key_name: { nested_key: 2 },
a: [{ nested_in_array: 1 }]
a: [{ nested_in_array_1: 1 }]
})
).toEqual({ keyName: { nestedKey: 2 }, a: [{ nestedInArray: 1 }] });
).toEqual({ keyName: { nestedKey: 2 }, a: [{ nestedInArray1: 1 }] });
});
});

Expand Down
8 changes: 3 additions & 5 deletions test/resources/Addresses.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import nock from "nock";
import { Address, Onfido } from "onfido-node";

const onfido = new Onfido({ apiToken: "api_token" });
import { Address } from "onfido-node";
import { createNock, onfido } from "../testHelpers";

const exampleAddress: Address = {
postcode: "S2 2DF",
Expand Down Expand Up @@ -34,7 +32,7 @@ const exampleAddressJson = {
};

it("allows picking addresses", async () => {
nock("https://api.onfido.com/v3")
createNock()
.get("/addresses/pick")
.query({ postcode: "S2 2DF" })
.reply(200, { addresses: [exampleAddressJson, exampleAddressJson] });
Expand Down
Loading

0 comments on commit 55490e0

Please sign in to comment.