@finverse/sdk-typescript 0.0.1-1646361421 → 0.0.1-1646789936
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -0
- package/dist/base.js +1 -1
- package/dist/test/accounts.spec.d.ts +1 -0
- package/dist/test/accounts.spec.js +38 -0
- package/dist/test/authenticate.spec.d.ts +1 -0
- package/dist/test/authenticate.spec.js +46 -0
- package/dist/test/config.d.ts +10 -0
- package/dist/test/config.js +15 -0
- package/dist/test/link.spec.d.ts +1 -0
- package/dist/test/link.spec.js +75 -0
- package/dist/test/loginIdentity.spec.d.ts +1 -0
- package/dist/test/loginIdentity.spec.js +69 -0
- package/dist/test/responses/account.d.ts +2 -0
- package/dist/test/responses/account.js +104 -0
- package/dist/test/responses/accountNumber.d.ts +2 -0
- package/dist/test/responses/accountNumber.js +19 -0
- package/dist/test/responses/balanceHistory.d.ts +2 -0
- package/dist/test/responses/balanceHistory.js +21 -0
- package/dist/test/responses/customerToken.d.ts +5 -0
- package/dist/test/responses/customerToken.js +8 -0
- package/dist/test/responses/identity.d.ts +2 -0
- package/dist/test/responses/identity.js +54 -0
- package/dist/test/responses/linkToken.d.ts +6 -0
- package/dist/test/responses/linkToken.js +9 -0
- package/dist/test/responses/loginIdentity.d.ts +2 -0
- package/dist/test/responses/loginIdentity.js +85 -0
- package/dist/test/responses/loginIdentityHistory.d.ts +2 -0
- package/dist/test/responses/loginIdentityHistory.js +37 -0
- package/dist/test/responses/loginIdentityToken.d.ts +7 -0
- package/dist/test/responses/loginIdentityToken.js +10 -0
- package/dist/test/responses/statement.d.ts +2 -0
- package/dist/test/responses/statement.js +20 -0
- package/dist/test/responses/statementLink.d.ts +2 -0
- package/dist/test/responses/statementLink.js +15 -0
- package/dist/test/responses/transaction.d.ts +2 -0
- package/dist/test/responses/transaction.js +280 -0
- package/dist/test/statements.spec.d.ts +1 -0
- package/dist/test/statements.spec.js +44 -0
- package/dist/test/transactions.spec.d.ts +1 -0
- package/dist/test/transactions.spec.js +38 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -1,2 +1,165 @@
|
|
|
1
1
|
# Finverse API - Typescript SDK
|
|
2
2
|
This SDK enables a basic end-to-end backend integration with the Finverse API, including API authentication, institution linking, and data retrieval.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
```
|
|
6
|
+
npm install @finverse/sdk-typescript
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Getting started
|
|
11
|
+
|
|
12
|
+
### 1. Authenticate with Finverse API: Obtain Customer Access Token
|
|
13
|
+
```typescript
|
|
14
|
+
// Obtain these from https://dashboard.finverse.com
|
|
15
|
+
const apiHost = "https://api.sandbox.finverse.net"
|
|
16
|
+
const clientId = process.env.FINVERSE_CLIENTID
|
|
17
|
+
const clientSecret = process.env.FINVERSE_SECRET
|
|
18
|
+
const redirectUri = process.env.REDIRECT_URI
|
|
19
|
+
|
|
20
|
+
const configuration = new Configuration({ basePath: apiHost });
|
|
21
|
+
// Obtain customer access token
|
|
22
|
+
const customerTokenResp = await new PublicApi(configuration).generateCustomerAccessToken({
|
|
23
|
+
client_id: clientId,
|
|
24
|
+
client_secret: clientSecret,
|
|
25
|
+
grant_type: 'client_credentials',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const customerAccessToken = customerTokenResp.access_token
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Link new institution: Obtain Link Token and Link URL to launch Finverse Link UI
|
|
32
|
+
```typescript
|
|
33
|
+
// generate a link token
|
|
34
|
+
|
|
35
|
+
// reference back to your system userId, finverse does not use this
|
|
36
|
+
const userId = "someUserId"
|
|
37
|
+
// this will be sent in the redirectUri callback, can be used to identify the state
|
|
38
|
+
const state = "someUniqueState"
|
|
39
|
+
const configuration = new Configuration({
|
|
40
|
+
basePath: apiHost,
|
|
41
|
+
accessToken: customerToken.access_token
|
|
42
|
+
});
|
|
43
|
+
const linkTokenResp = await new CustomerApi(configuration).generateLinkToken({
|
|
44
|
+
ClientId: clientId,
|
|
45
|
+
UserId: userId,
|
|
46
|
+
RedirectUri: redirectUri,
|
|
47
|
+
State: state,
|
|
48
|
+
ResponseMode: "form_post",
|
|
49
|
+
ResponseType: "code",
|
|
50
|
+
GrantType: "client_credentials",
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// The linkUrl can be used to initiate Finverse Link
|
|
54
|
+
console.log("linkUrl: " + linkTokenResp.link_url)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3. Finalize linking: Exchange code for Login Identity Access Token
|
|
58
|
+
```typescript
|
|
59
|
+
// when Finverse Link UI is successful, obtain the code from Finverse Link
|
|
60
|
+
// exchange it for a Login Identity Access Token
|
|
61
|
+
const code = "obtainAfterLink"
|
|
62
|
+
const configuration = new Configuration({
|
|
63
|
+
basePath: apiHost,
|
|
64
|
+
accessToken: customerToken.access_token
|
|
65
|
+
});
|
|
66
|
+
const loginIdentityTokenResp = await new LinkApi(configuration).token(
|
|
67
|
+
"authorization_code",
|
|
68
|
+
code,
|
|
69
|
+
clientId,
|
|
70
|
+
redirectURI,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// The loginIdentityToken can be used to retrieve data
|
|
74
|
+
const loginIdentityToken = loginIdentityTokenResp.access_token
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 4. Retrieve data: Get data using Login Identity Access Token
|
|
78
|
+
```typescript
|
|
79
|
+
// get LoginIdentity
|
|
80
|
+
const configuration = new Configuration({
|
|
81
|
+
basePath: apiHost,
|
|
82
|
+
accessToken: loginIdentityToken.access_token
|
|
83
|
+
});
|
|
84
|
+
const loginIdentityResp = await new LoginIdentityApi(configuration).getLoginIdentity();
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
console.log("login identity: " + loginIdentityResp.login_identity)
|
|
88
|
+
|
|
89
|
+
// get other products (Accounts, Account Numbers, Transactions)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
### 5. Poll loginIdentityStatus until ready
|
|
94
|
+
```typescript
|
|
95
|
+
enum FinalStatus {
|
|
96
|
+
ERROR = 'ERROR',
|
|
97
|
+
DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL = 'DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL',
|
|
98
|
+
DATA_RETRIEVAL_COMPLETE = 'DATA_RETRIEVAL_COMPLETE',
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const configuration = new Configuration({
|
|
102
|
+
basePath: apiHost,
|
|
103
|
+
accessToken: loginIdentityToken.access_token
|
|
104
|
+
});
|
|
105
|
+
let loginIdentity: AxiosResponse<GetLoginIdentityByIdResponse>;
|
|
106
|
+
|
|
107
|
+
// Poll until loginIdentityStatus is ready
|
|
108
|
+
for (let i = 0; i < 20; i++) {
|
|
109
|
+
loginIdentity = await new LoginIdentityApi(configuration).getLoginIdentity();
|
|
110
|
+
const loginIdentityStatus = loginIdentity.data.login_identity.status;
|
|
111
|
+
if (
|
|
112
|
+
loginIdentityStatus === FinalStatus.ERROR ||
|
|
113
|
+
loginIdentityStatus === FinalStatus.DATA_RETRIEVAL_COMPLETE ||
|
|
114
|
+
loginIdentityStatus === FinalStatus.DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL
|
|
115
|
+
) {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
console.log("login identity: " + loginIdentityResp.login_identity)
|
|
122
|
+
// get other products (Accounts, Account Numbers, Transactions)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 6. Get Accounts
|
|
126
|
+
```typescript
|
|
127
|
+
// Get Accounts
|
|
128
|
+
const configuration = new Configuration({ basePath: apiHost, accessToken: loginIdentityToken.access_token });
|
|
129
|
+
const accountsRsp = await new LoginIdentityApi(configuration).listAccounts();
|
|
130
|
+
|
|
131
|
+
console.log("accounts: " + accountsResp.accounts)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 7. Get Transactions
|
|
135
|
+
```typescript
|
|
136
|
+
// Get Transactions with pagination using offset and limit
|
|
137
|
+
let offset = 0
|
|
138
|
+
while(true) {
|
|
139
|
+
const configuration = new Configuration({ basePath: apiHost, accessToken: loginIdentityToken.access_token });
|
|
140
|
+
const transactionsResp = await new LoginIdentityApi(configuration).listTransactionsByLoginIdentityId();
|
|
141
|
+
|
|
142
|
+
console.log(`total: ${transactionsResp.total_transactions}, transactions: ${transactionsResp.transactions}`)
|
|
143
|
+
offset += transactionsResp.transactions.length
|
|
144
|
+
|
|
145
|
+
if offset >= transactionsResp.total_transactions {
|
|
146
|
+
break
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 8. Get Statements
|
|
152
|
+
```typescript
|
|
153
|
+
// Get Statements metadata
|
|
154
|
+
const configuration = new Configuration({ basePath: apiHost, accessToken: loginIdentityToken.access_token });
|
|
155
|
+
const statements = await new LoginIdentityApi(configuration).getStatements();
|
|
156
|
+
|
|
157
|
+
console.log("statements: " + statementsResp.statements)
|
|
158
|
+
|
|
159
|
+
// Get link to statement
|
|
160
|
+
// Assuming there is only one statement
|
|
161
|
+
const statementId = statements.data.statements[0].id;
|
|
162
|
+
|
|
163
|
+
// Can download statement from here
|
|
164
|
+
const satementLink = await new LoginIdentityApi(configuration).getStatementLink(statementId);
|
|
165
|
+
```
|
package/dist/base.js
CHANGED
|
@@ -17,7 +17,7 @@ exports.RequiredError = exports.BaseAPI = exports.COLLECTION_FORMATS = exports.B
|
|
|
17
17
|
// Some imports not used depending on template conditions
|
|
18
18
|
// @ts-ignore
|
|
19
19
|
const axios_1 = require("axios");
|
|
20
|
-
exports.BASE_PATH = '
|
|
20
|
+
exports.BASE_PATH = 'https://api.sandbox.finverse.net'.replace(/\/+$/, '');
|
|
21
21
|
/**
|
|
22
22
|
*
|
|
23
23
|
* @export
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const axios_mock_adapter_1 = require("axios-mock-adapter");
|
|
13
|
+
const axios_1 = require("axios");
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const __1 = require("..");
|
|
16
|
+
const api_1 = require("../api");
|
|
17
|
+
const account_1 = require("./responses/account");
|
|
18
|
+
const loginIdentityToken_1 = require("./responses/loginIdentityToken");
|
|
19
|
+
const chai_1 = require("chai");
|
|
20
|
+
describe('Accounts', function () {
|
|
21
|
+
let mock;
|
|
22
|
+
before(() => {
|
|
23
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
24
|
+
mock.onGet(`${config_1.config.apiHost}/accounts`).reply(200, account_1.getAccounts());
|
|
25
|
+
});
|
|
26
|
+
it('Get accounts', function () {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
// Make Request
|
|
29
|
+
const configuration = new __1.Configuration({ basePath: config_1.config.apiHost, accessToken: loginIdentityToken_1.loginIdentityToken.access_token });
|
|
30
|
+
const got = yield new api_1.LoginIdentityApi(configuration).listAccounts();
|
|
31
|
+
// Expect
|
|
32
|
+
chai_1.expect(got.data.accounts).to.be.ok;
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
after(() => {
|
|
36
|
+
mock.restore();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const axios_mock_adapter_1 = require("axios-mock-adapter");
|
|
13
|
+
const axios_1 = require("axios");
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const __1 = require("..");
|
|
16
|
+
const customerToken_1 = require("./responses/customerToken");
|
|
17
|
+
const chai_1 = require("chai");
|
|
18
|
+
describe('Authenticate', function () {
|
|
19
|
+
let mock;
|
|
20
|
+
before(() => {
|
|
21
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
22
|
+
mock
|
|
23
|
+
.onPost(`${config_1.config.apiHost}/auth/customer/token`, {
|
|
24
|
+
client_id: config_1.config.clientId,
|
|
25
|
+
client_secret: config_1.config.clientSecret,
|
|
26
|
+
grant_type: config_1.grantType.CLIENT_CREDENTIALS,
|
|
27
|
+
})
|
|
28
|
+
.reply(200, customerToken_1.customerToken);
|
|
29
|
+
});
|
|
30
|
+
it('Get customer access token', function () {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
// Make Request
|
|
33
|
+
const configuration = new __1.Configuration({ basePath: config_1.config.apiHost });
|
|
34
|
+
const got = yield new __1.PublicApi(configuration).generateCustomerAccessToken({
|
|
35
|
+
client_id: config_1.config.clientId,
|
|
36
|
+
client_secret: config_1.config.clientSecret,
|
|
37
|
+
grant_type: config_1.grantType.CLIENT_CREDENTIALS,
|
|
38
|
+
});
|
|
39
|
+
// Expect
|
|
40
|
+
chai_1.expect(got.data.access_token).to.equal(customerToken_1.customerToken.access_token);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
after(() => {
|
|
44
|
+
mock.restore();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.grantType = exports.config = void 0;
|
|
4
|
+
// These are being hardcoded for the test.
|
|
5
|
+
// Obtain these from https://dashboard.finverse.com
|
|
6
|
+
exports.config = {
|
|
7
|
+
apiHost: 'https://example.com',
|
|
8
|
+
redirectURI: 'https://example.com/callback',
|
|
9
|
+
clientId: 'clientId',
|
|
10
|
+
clientSecret: 'clientSecret',
|
|
11
|
+
};
|
|
12
|
+
exports.grantType = {
|
|
13
|
+
AUTHORIZATION_CODE: 'authorization_code',
|
|
14
|
+
CLIENT_CREDENTIALS: 'client_credentials',
|
|
15
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const axios_mock_adapter_1 = require("axios-mock-adapter");
|
|
13
|
+
const axios_1 = require("axios");
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const __1 = require("..");
|
|
16
|
+
const api_1 = require("../api");
|
|
17
|
+
const linkToken_1 = require("./responses/linkToken");
|
|
18
|
+
const customerToken_1 = require("./responses/customerToken");
|
|
19
|
+
const loginIdentityToken_1 = require("./responses/loginIdentityToken");
|
|
20
|
+
const chai_1 = require("chai");
|
|
21
|
+
describe('Link', function () {
|
|
22
|
+
let mock;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
25
|
+
});
|
|
26
|
+
it('Obtain link token and link url to launch Finverse Link UI', function () {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
// Variables
|
|
29
|
+
const url = `${config_1.config.apiHost}/link/token`;
|
|
30
|
+
const requestBody = {
|
|
31
|
+
client_id: config_1.config.clientId,
|
|
32
|
+
grant_type: config_1.grantType.CLIENT_CREDENTIALS,
|
|
33
|
+
user_id: 'userId',
|
|
34
|
+
redirect_uri: config_1.config.redirectURI,
|
|
35
|
+
state: 'state',
|
|
36
|
+
response_mode: 'form_post',
|
|
37
|
+
response_type: 'code',
|
|
38
|
+
link_mode: 'iframe',
|
|
39
|
+
};
|
|
40
|
+
// Mocking
|
|
41
|
+
mock.onPost(url, requestBody).reply(200, linkToken_1.linkToken);
|
|
42
|
+
// Make Request
|
|
43
|
+
const configuration = new __1.Configuration({ basePath: config_1.config.apiHost, accessToken: customerToken_1.customerToken.access_token });
|
|
44
|
+
const got = yield new api_1.CustomerApi(configuration).generateLinkToken(requestBody);
|
|
45
|
+
// Expect
|
|
46
|
+
// The link url is used to initialize Finverse Link, when linking is finished, a cose is sent to the redirectUri
|
|
47
|
+
// This is used to exchange for loginIdentity Token
|
|
48
|
+
chai_1.expect(got.data.link_url).to.equal(linkToken_1.linkToken.link_url);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
it('Obtain login identity token', function () {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
// Variables
|
|
54
|
+
const url = `${config_1.config.apiHost}/auth/token`;
|
|
55
|
+
const requestBody = new URLSearchParams({
|
|
56
|
+
grant_type: config_1.grantType.AUTHORIZATION_CODE,
|
|
57
|
+
code: 'obtainAfterLink',
|
|
58
|
+
client_id: config_1.config.clientId,
|
|
59
|
+
redirect_uri: config_1.config.redirectURI,
|
|
60
|
+
});
|
|
61
|
+
// Mocking
|
|
62
|
+
// When Finverse link is done, obtain the code and use it to exchange for login identity access token
|
|
63
|
+
mock.onPost(url, requestBody.toString()).reply(200, loginIdentityToken_1.loginIdentityToken);
|
|
64
|
+
// Make Request
|
|
65
|
+
const configuration = new __1.Configuration({ basePath: config_1.config.apiHost, accessToken: customerToken_1.customerToken.access_token });
|
|
66
|
+
const got = yield new api_1.LinkApi(configuration).token(config_1.grantType.AUTHORIZATION_CODE, 'obtainAfterLink', config_1.config.clientId, config_1.config.redirectURI);
|
|
67
|
+
// Expect
|
|
68
|
+
// The loginIdentityToken can be used to retrieve data
|
|
69
|
+
chai_1.expect(got.data.access_token).to.equal(loginIdentityToken_1.loginIdentityToken.access_token);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
mock.restore();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const axios_mock_adapter_1 = require("axios-mock-adapter");
|
|
13
|
+
const axios_1 = require("axios");
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const __1 = require("..");
|
|
16
|
+
const api_1 = require("../api");
|
|
17
|
+
const loginIdentity_1 = require("./responses/loginIdentity");
|
|
18
|
+
const loginIdentityToken_1 = require("./responses/loginIdentityToken");
|
|
19
|
+
const chai_1 = require("chai");
|
|
20
|
+
var FinalStatus;
|
|
21
|
+
(function (FinalStatus) {
|
|
22
|
+
FinalStatus["ERROR"] = "ERROR";
|
|
23
|
+
FinalStatus["DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL"] = "DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL";
|
|
24
|
+
FinalStatus["DATA_RETRIEVAL_COMPLETE"] = "DATA_RETRIEVAL_COMPLETE";
|
|
25
|
+
})(FinalStatus || (FinalStatus = {}));
|
|
26
|
+
describe('Login Identity', function () {
|
|
27
|
+
let mock;
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
30
|
+
mock.onGet(`${config_1.config.apiHost}/login_identity`).reply(200, loginIdentity_1.getLoginIdentity());
|
|
31
|
+
});
|
|
32
|
+
it('Obtain login identity', function () {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
// Make Request
|
|
35
|
+
const configuration = new __1.Configuration({ basePath: config_1.config.apiHost, accessToken: loginIdentityToken_1.loginIdentityToken.access_token });
|
|
36
|
+
const got = yield new api_1.LoginIdentityApi(configuration).getLoginIdentity();
|
|
37
|
+
// Expect
|
|
38
|
+
// This is the institution information
|
|
39
|
+
chai_1.expect(got.data.institution).to.be.ok;
|
|
40
|
+
// This is the login identity events
|
|
41
|
+
chai_1.expect(got.data.login_identity).to.be.ok;
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it('Poll login identity until ready', function () {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
// Make Request
|
|
47
|
+
const configuration = new __1.Configuration({ basePath: config_1.config.apiHost, accessToken: loginIdentityToken_1.loginIdentityToken.access_token });
|
|
48
|
+
let got;
|
|
49
|
+
for (let i = 0; i < 20; i++) {
|
|
50
|
+
got = yield new api_1.LoginIdentityApi(configuration).getLoginIdentity();
|
|
51
|
+
const loginIdentityStatus = got.data.login_identity.status;
|
|
52
|
+
if (loginIdentityStatus === FinalStatus.ERROR ||
|
|
53
|
+
loginIdentityStatus === FinalStatus.DATA_RETRIEVAL_COMPLETE ||
|
|
54
|
+
loginIdentityStatus === FinalStatus.DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
yield new Promise((resolve) => setTimeout(resolve, 3000));
|
|
58
|
+
}
|
|
59
|
+
// Expect
|
|
60
|
+
// This is the institution information
|
|
61
|
+
chai_1.expect(got.data.institution).to.be.ok;
|
|
62
|
+
// This is the login identity events
|
|
63
|
+
chai_1.expect(got.data.login_identity).to.be.ok;
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
afterEach(() => {
|
|
67
|
+
mock.restore();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAccounts = void 0;
|
|
4
|
+
function getAccounts() {
|
|
5
|
+
return {
|
|
6
|
+
accounts: [
|
|
7
|
+
{
|
|
8
|
+
account_currency: 'HKD',
|
|
9
|
+
account_id: '01F7MP3XTNX36K9N66JPKH131P',
|
|
10
|
+
account_name: 'HKD Checking',
|
|
11
|
+
balance: {
|
|
12
|
+
currency: 'HKD',
|
|
13
|
+
raw: '70013.12',
|
|
14
|
+
value: 70013.12,
|
|
15
|
+
},
|
|
16
|
+
created_at: '2021-06-08T02:09:42.000Z',
|
|
17
|
+
group_id: '5578758a56843bbe7104f0915f807eae4231aa0e5ce2bc0950c4fcb372b85948',
|
|
18
|
+
is_closed: false,
|
|
19
|
+
is_excluded: false,
|
|
20
|
+
is_parent: false,
|
|
21
|
+
statement_balance: {
|
|
22
|
+
currency: 'HKD',
|
|
23
|
+
raw: '70013.12',
|
|
24
|
+
value: 70013.12,
|
|
25
|
+
},
|
|
26
|
+
updated_at: '2021-06-08T02:09:42.000Z',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
account_currency: 'HKD',
|
|
30
|
+
account_id: '01F7MP3XTQ4Y8AFQ9KDFQXF14Y',
|
|
31
|
+
account_name: 'HKD Credit Card',
|
|
32
|
+
balance: {
|
|
33
|
+
currency: 'HKD',
|
|
34
|
+
raw: '-1833.22',
|
|
35
|
+
value: -1833.22,
|
|
36
|
+
},
|
|
37
|
+
created_at: '2021-06-08T02:09:42.000Z',
|
|
38
|
+
group_id: '4f776329e40d2aafaeb33415283aea9e0dae84467aeaa51c5030e4b0311b6040',
|
|
39
|
+
is_closed: false,
|
|
40
|
+
is_excluded: false,
|
|
41
|
+
is_parent: false,
|
|
42
|
+
statement_balance: {
|
|
43
|
+
currency: 'HKD',
|
|
44
|
+
raw: '-1833.22',
|
|
45
|
+
value: -1833.22,
|
|
46
|
+
},
|
|
47
|
+
updated_at: '2021-06-08T02:09:42.000Z',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
account_currency: 'USD',
|
|
51
|
+
account_id: '01F7MP3XTSBSTG6G68FESC66B1',
|
|
52
|
+
account_name: 'USD FX',
|
|
53
|
+
balance: {
|
|
54
|
+
currency: 'USD',
|
|
55
|
+
raw: '1923.22',
|
|
56
|
+
value: 1923.22,
|
|
57
|
+
},
|
|
58
|
+
created_at: '2021-06-08T02:09:42.000Z',
|
|
59
|
+
group_id: '582c1d9912586672ef9d028d7ed521ffedf9bb11d2392ddf1c2ec2e231c49ce5',
|
|
60
|
+
is_closed: false,
|
|
61
|
+
is_excluded: false,
|
|
62
|
+
is_parent: false,
|
|
63
|
+
statement_balance: {
|
|
64
|
+
currency: 'HKD',
|
|
65
|
+
raw: '15001.116',
|
|
66
|
+
value: 15001.116,
|
|
67
|
+
},
|
|
68
|
+
updated_at: '2021-06-08T02:09:42.000Z',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
account_currency: 'BTC',
|
|
72
|
+
account_id: '01F7MP3XTV38VSZMVF4C65NHT3',
|
|
73
|
+
account_name: 'Bitcoin',
|
|
74
|
+
balance: {
|
|
75
|
+
currency: 'BTC',
|
|
76
|
+
raw: '420.69',
|
|
77
|
+
value: 420.69,
|
|
78
|
+
},
|
|
79
|
+
created_at: '2021-06-08T02:09:42.000Z',
|
|
80
|
+
group_id: '582c1d9912586672ef9d028d7ed521ffedf9bb11d2392ddf1c2ec2e231c49ce5',
|
|
81
|
+
is_closed: false,
|
|
82
|
+
is_excluded: false,
|
|
83
|
+
is_parent: false,
|
|
84
|
+
statement_balance: {
|
|
85
|
+
currency: 'HKD',
|
|
86
|
+
raw: '106468292.05',
|
|
87
|
+
value: 106468292.05,
|
|
88
|
+
},
|
|
89
|
+
updated_at: '2021-06-08T02:09:42.000Z',
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
institution: {
|
|
93
|
+
countries: ['HKG', 'SGP', 'PHL'],
|
|
94
|
+
institution_id: 'testbank',
|
|
95
|
+
institution_name: 'TestBank HK',
|
|
96
|
+
portal_name: 'Test Bank Personal Account',
|
|
97
|
+
},
|
|
98
|
+
login_identity: {
|
|
99
|
+
login_identity_id: '01F7MP3J3H485QSDQC0FS15KE7',
|
|
100
|
+
status: 'DATA_RETRIEVAL_COMPLETE',
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
exports.getAccounts = getAccounts;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAccountNumber = void 0;
|
|
4
|
+
const account_1 = require("./account");
|
|
5
|
+
function getAccountNumber() {
|
|
6
|
+
var _a;
|
|
7
|
+
const accountData = account_1.getAccounts();
|
|
8
|
+
return {
|
|
9
|
+
account: (_a = accountData === null || accountData === void 0 ? void 0 : accountData.accounts) === null || _a === void 0 ? void 0 : _a[0],
|
|
10
|
+
account_number: {
|
|
11
|
+
raw: '123-456789-123',
|
|
12
|
+
number: '123456789123',
|
|
13
|
+
account_id: 'validId',
|
|
14
|
+
},
|
|
15
|
+
institution: accountData.institution,
|
|
16
|
+
login_identity: accountData.login_identity,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
exports.getAccountNumber = getAccountNumber;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBalanceHistory = void 0;
|
|
4
|
+
const account_1 = require("./account");
|
|
5
|
+
function getBalanceHistory() {
|
|
6
|
+
var _a;
|
|
7
|
+
const accountData = account_1.getAccounts();
|
|
8
|
+
return {
|
|
9
|
+
account: (_a = accountData === null || accountData === void 0 ? void 0 : accountData.accounts) === null || _a === void 0 ? void 0 : _a[0],
|
|
10
|
+
balance_history: [
|
|
11
|
+
{
|
|
12
|
+
amount: 69,
|
|
13
|
+
currency: 'HKD',
|
|
14
|
+
date: '2021-10-27',
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
institution: accountData.institution,
|
|
18
|
+
login_identity: accountData.login_identity,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
exports.getBalanceHistory = getBalanceHistory;
|