Skip to content

Commit

Permalink
feat(number-insight-v2): added support for number insight v2
Browse files Browse the repository at this point in the history
  • Loading branch information
manchuck committed Oct 12, 2023
1 parent 670b83c commit bb08004
Show file tree
Hide file tree
Showing 30 changed files with 439 additions and 2 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ You can find more information for each product below:
* [Auth][auth]
* [JWT][jwt]
* [Messages](https://github.com/Vonage/vonage-node-sdk/blob/3.x/packages/messages/README.md)
* [Number Insight V2](https://github.com/Vonage/vonage-node-sdk/blob/3.x/packages/number-insight-v2/README.md)
* [Number Insights](https://github.com/Vonage/vonage-node-sdk/blob/3.x/packages/number-insights/README.md)
* [Numbers](https://github.com/Vonage/vonage-node-sdk/blob/3.x/packages/numbers/README.md)
* [Pricing](https://github.com/Vonage/vonage-node-sdk/blob/3.x/packages/pricing/README.md)
Expand Down Expand Up @@ -109,7 +110,8 @@ The following is a list of Vonage APIs and whether the Node Server SDK provides
| External Accounts API | Beta ||
| Media API | Beta ||
| Messages API | Beta ||
| Number Insight API | General Availability ||
| Number Insight V2 API | Beta ||
| Number Insights API | General Availability ||
| Number Management API | General Availability ||
| Pricing API | General Availability ||
| Proactive Connect API | Beta ||
Expand Down
7 changes: 7 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ const config: Config.InitialOptions = {
testMatch: ['<rootDir>/packages/meetings/__tests__/**/*.test.ts'],
coveragePathIgnorePatterns: ['node_modules', '__tests__'],
},
{
displayName: 'NUMBER INSIGHT V2',
testMatch: [
'<rootDir>/packages/number-insight-v2/__tests__/**/*.test.ts',
],
coveragePathIgnorePatterns: ['node_modules', '__tests__'],
},
{
displayName: 'NUMBER INSIGHTS',
testMatch: ['<rootDir>/packages/number-insights/__tests__/**/*.test.ts'],
Expand Down
105 changes: 105 additions & 0 deletions packages/number-insight-v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Vonage Number Insight V2 SDK for Node.js

![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/vonage/vonage-node-sdk/ci.yml?branch=3.x) [![Codecov](https://img.shields.io/codecov/c/github/vonage/vonage-node-sdk?label=Codecov&logo=codecov&style=flat-square)](https://codecov.io/gh/Vonage/vonage-server-sdk) ![Latest Release](https://img.shields.io/npm/v/@vonage/number-insight-v2?label=%40vonage%2Fnumber-insights&style=flat-square) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg?style=flat-square)](../../CODE_OF_CONDUCT.md) [![License](https://img.shields.io/npm/l/@vonage/accounts?label=License&style=flat-square)][license]

<img src="https://developer.nexmo.com/images/logos/vbc-logo.svg" height="48px" alt="Vonage" />

This is the Vonage Number Insight V2 SDK for Node.js for use with [Vonage APIs](https://www.vonage.com/). To use it you will need a Vonage account. Sign up [for free at vonage.com][signup].

For full API documentation refer to [developer.nexmo.com](https://developer.nexmo.com/).

* [Installation](#installation)
* [Usage](#usage)
* [Promises](#promises)
* [Testing](#testing)

## Installation

We recommend using this SDK as part of the overall [`@vonage/server-sdk` package](https://github.com/vonage/vonage-node-sdk). Please see the main package for installation.

You can also use this SDK standalone if you only need access to just the Number insights V2 API.

### With NPM

```bash
npm install @vonage/number-insight-v2
```

### With Yarn

```bash
yarn add @vonage/number-insight-v2
```

## Usage

### As part of the Vonage Server SDK

If you are using this SDK as part of the Vonage Server SDK, you can access it as the `numberInsightV2` property off of the client that you instantiate.

```js
const { Auth } = require('@vonage/auth);
const { Vonage } = require('@vonage/server-sdk');
const { Insight } = require('@vonage/number-insight-v2');
const credentials = new Auth({
apiKey: API_KEY,
apiSecret: API_SECRET
});
const options = {};
const vonage = new Vonage(credentials, options);
vonage.numberInsightV2.checkForFraud({
type: 'phone',
phone: PHONE_NUMBER,
insights: [Insight.SIM_SWAP, Insight.FRAUD_SCORE],
})
.then(resp => console.log(resp))
.catch(err => console.error(err));
```
### Standalone
The SDK can be used standalone from the main [Vonage Server SDK for Node.js](https://github.com/vonage/vonage-node-sdk) if you only need to use the Number Insight v2 API. All you need to do is `require('@vonage/number-insight-v2')`, and use the returned object to create your own client.
```js
const { Auth } = require('@vonage/auth');
const { NumberInsightV2 } = require('@vonage/number-insight-v2');
const credentials = new Auth({
apiKey: API_KEY,
apiSecret: API_SECRET
});
const options = {};
const niClient = new NumberInsightV2(credentials, options);
```
Where `credentials` is any option from [`@vonage/auth`](https://github.com/Vonage/vonage-node-sdk/blob/3.x/packages/auth/README.md#options), and `options` is any option from [`@vonage/server-client`](https://github.com/Vonage/vonage-node-sdk/blob/3.x/packages/server-client/README.md#options)
## Promises
Most methods that interact with the Vonage API uses Promises. You can either resolve these yourself, or use `await` to wait for a response.
```js
const resp = await vonage.numberInsightV2.basicLookup(PHONE_NUMBER)
vonage.numberInsightV2.checkForFraud({
type: 'phone',
phone: PHONE_NUMBER,
insights: [Insight.SIM_SWAP, Insight.FRAUD_SCORE],
})
.then(resp => console.log(resp))
.catch(err => console.error(err));
```
## Testing
Run:
```bash
npm run test
```
[signup]: https://dashboard.nexmo.com/sign-up?utm_source=DEV_REL&utm_medium=github&utm_campaign=node-server-sdk
[license]: ../../LICENSE.txt
8 changes: 8 additions & 0 deletions packages/number-insight-v2/__tests__/__dataSets__/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import postTests from './post';

export default [
{
label: 'Check For Fraud',
tests: postTests,
},
];
69 changes: 69 additions & 0 deletions packages/number-insight-v2/__tests__/__dataSets__/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
Status,
FraudCheckResponse,
FraudCheckParameters,
Insight,
FraudCheck,
Label,
RiskRecommendation,
FraudScoreResponse,
} from '../../lib';

const params = {
type: 'phone',
phone: '16127779311',
insights: [Insight.SIM_SWAP, Insight.FRAUD_SCORE],
} as FraudCheckParameters;

const fraudCheck = {
requestId: '00000000-0000-0000-0000-000000000000',
type: 'phone',
phone: {
phone: '16127779311',
carrier: 'Google (Grand Central) - SVR',
type: 'VOIP',
},
fraudScore: {
riskScore: '20',
riskRecommendation: RiskRecommendation.ALLOW,
label: Label.LOW,
status: Status.COMPLETED,
},
simSwap: {
status: Status.COMPLETED,
swapped: false,
},
} as FraudCheck;

const response = {
request_id: '00000000-0000-0000-0000-000000000000',
type: 'phone',
phone: {
phone: '16127779311',
carrier: 'Google (Grand Central) - SVR',
type: 'VOIP',
},
fraud_score: {
risk_score: '20',
risk_recommendation: 'allow',
label: 'low',
status: 'completed',
} as FraudScoreResponse,
sim_swap: {
status: 'completed',
swapped: false,
},
} as FraudCheckResponse;

export default [
{
label: 'check for fraud',
requests: [[`/v2/ni`, 'POST', params]],
responses: [[200, response]],
clientMethod: 'checkForFraud',
parameters: [params],
generator: false,
error: false,
expected: fraudCheck,
},
];
1 change: 1 addition & 0 deletions packages/number-insight-v2/__tests__/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const BASE_URL = 'https://api.nexmo.com/';
48 changes: 48 additions & 0 deletions packages/number-insight-v2/__tests__/numberInsightV2.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { NumberInsightV2 } from '../lib/index';
import nock from 'nock';
import { Auth } from '@vonage/auth';
import { BASE_URL } from './common';
import testDataSets from './__dataSets__/index';
import { readFileSync } from 'fs';

const key = readFileSync(`${__dirname}/private.test.key`).toString();

describe.each(testDataSets)('$label', ({ tests }) => {
let client;
let scope;

beforeEach(function () {
client = new NumberInsightV2(
new Auth({
privateKey: key,
applicationId: 'my-application',
}),
);

scope = nock(BASE_URL, {
reqheaders: {
authorization: (value) => value.startsWith('Bearer '),
},
}).persist();
});

afterEach(function () {
client = null;
scope = null;
nock.cleanAll();
});

test.each(tests)(
'Can $label using: $clientMethod',
async ({ requests, responses, clientMethod, parameters, expected }) => {
requests.forEach((request, index) => {
scope.intercept(...request).reply(...responses[index]);
});

const result = await client[clientMethod](...parameters);

expect(result).toEqual(expected);
expect(nock.isDone()).toBeTruthy();
},
);
});
28 changes: 28 additions & 0 deletions packages/number-insight-v2/__tests__/private.test.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB
ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN
MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX
yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx
ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95
Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc
a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX
ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU
Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u
4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP
Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom
mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz
n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx
mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM
70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO
PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU
k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK
uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b
T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy
q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA
KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw
uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ
34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va
OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty
LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n
doWDENAr/VU1RNCDwFdxYFg=
-----END PRIVATE KEY-----
4 changes: 4 additions & 0 deletions packages/number-insight-v2/lib/enums/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './insight';
export * from './label';
export * from './riskRecommendation';
export * from './status';
4 changes: 4 additions & 0 deletions packages/number-insight-v2/lib/enums/insight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum Insight {
FRAUD_SCORE = 'fraud_score',
SIM_SWAP = 'sim_swap',
}
5 changes: 5 additions & 0 deletions packages/number-insight-v2/lib/enums/label.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum Label {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
}
5 changes: 5 additions & 0 deletions packages/number-insight-v2/lib/enums/riskRecommendation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum RiskRecommendation {
ALLOW = 'allow',
FLAG = 'flag',
BLOCK = 'block',
}
4 changes: 4 additions & 0 deletions packages/number-insight-v2/lib/enums/status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum Status {
COMPLETED = 'completed',
FAILED = 'failed',
}
3 changes: 3 additions & 0 deletions packages/number-insight-v2/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './enums';
export * from './numberInsightV2';
export * from './types';
15 changes: 15 additions & 0 deletions packages/number-insight-v2/lib/numberInsightV2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Client, AuthenticationType } from '@vonage/server-client';
import { FraudCheckParameters, FraudScore, FraudScoreResponse } from './types';

export class NumberInsightV2 extends Client {
protected authType = AuthenticationType.JWT;

async checkForFraud(params: FraudCheckParameters): Promise<FraudScore> {
const resp = await this.sendPostRequest<FraudScoreResponse>(
`${this.config.apiHost}/v2/ni`,
params,
);

return Client.transformers.camelCaseObjectKeys(resp?.data, true);
}
}
11 changes: 11 additions & 0 deletions packages/number-insight-v2/lib/types/fraudCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { PhoneInfo } from './phoneInfo';
import { FraudScore } from './fraudScore';
import { SimSwap } from './simSwap';

export type FraudCheck = {
requestId: string;
type: 'phone';
phone: PhoneInfo;
fraudScore?: FraudScore;
simSwap?: SimSwap;
};
8 changes: 8 additions & 0 deletions packages/number-insight-v2/lib/types/fraudScore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { RiskRecommendation, Label, Status } from '../enums';

export type FraudScore = {
riskScore: string;
riskRecommendation: RiskRecommendation;
label: Label;
status: Status;
};
7 changes: 7 additions & 0 deletions packages/number-insight-v2/lib/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './fraudCheck';
export * from './fraudScore';
export * from './parameters';
export * from './phoneInfo';
export * from './requests';
export * from './responses';
export * from './simSwap';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Insight } from '../../enums/';

export type FraudCheckParameters = {
type: 'phone';
phone: string;
insights: Insight[];
};
1 change: 1 addition & 0 deletions packages/number-insight-v2/lib/types/parameters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './fraudParameters';
5 changes: 5 additions & 0 deletions packages/number-insight-v2/lib/types/phoneInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type PhoneInfo = {
phone: string;
carrier?: string;
type?: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Insight } from '../../enums';

export type FraudCheckRequest = {
type: 'phone';
phone: string;
insights: Insight[];
};
1 change: 1 addition & 0 deletions packages/number-insight-v2/lib/types/requests/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './fraudCheckRequest';
Loading

0 comments on commit bb08004

Please sign in to comment.