Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,80 @@ mtLinkSdk.openService(serviceId, options);
| - | - | - | - | - |
| serviceId | `vault`, `myaccount-settings`, `link-kit` | true | | Open a service by Id, current supported services are:<br /><li>`vault` - Manage your financial institution credentials.</li><li>`myaccount-settings` - Manage your Moneytree account settings.</li><li>`link-kit` - View all your financial data.<br /><br /><strong>NOTE:</strong> This function will throw an error if you do not specify a valid service ID. |
| options | object | false | Value set during `init`. | Optional parameters. Includes all options in [common options](#common-api-options). |
| options.view | `services-list`, `service-connection`, `connection-setting`, `customer-support` | false | | We provide the way to open the Vault's specific pages. Please check the following sessions:<br /> <li>[Open Vault Services Page](#open-vault-services-page)</li><li>[Open Vault Service Connection Page](#open-vault-service-connection-page)</li><li>[Open Vault Service Setting Page](#open-vault-service-setting-page)</li><li>[Open Vault Customer Support Page](#open-vault-customer-support-page)</li> <br /><br /><strong>NOTE:</strong> The serviceId must be `vault` to enable this option.|

#### Open Vault Services Page

It has to include these properties of `options` below when calling [openService](#openservice) API.

<strong>NOTE:</strong> This scenario only works when serviceId is `vault`.

<h6>Usage:</h6>

```javascript
mtLinkSdk.openService('vault', { view: 'services-list', type: 'bank', group: 'grouping_bank', search: 'japan' });
```

| Parameter | Type | Required | Default Value | Description |
| - | - | - | - | - |
| serviceId | `vault` | true | | Open a Vault service.|
| options.view | `services-list` | true | | Assign to open services page.|
| options.type | `bank` (personal bank), <br />`credit_card` (personal credit card), <br />`stored_value` (electronic money), `point` (loyalty point), <br />`corporate` (corporate bank or card) | false | | Filter the services by type. |
| options.group | `grouping_bank`, `grouping_bank_credit_card`, `grouping_bank_dc_card`, `grouping_corporate_credit_card`, `grouping_credit_card`, `grouping_credit_coop`, `grouping_credit_union`, `grouping_dc_pension_plan`, `grouping_debit_card`, `grouping_digital_money`, `grouping_ja_bank`, `grouping_life_insurance`, `grouping_point`, `grouping_regional_bank`, `grouping_stock`, `grouping_testing` | false | | Filter the services by group. |
| options.search | string | false | | Filter the services by the search term. |

#### Open Vault Service Connection Page

It has to include these properties of `options` below when calling [openService](#openservice) API.

<strong>NOTE:</strong> This scenario only works when serviceId is `vault`.

<h6>Usage:</h6>

```javascript
mtLinkSdk.openService('vault', { view: 'service-connection', entityKey: 'yucho_bank'});
```

| Parameter | Type | Required | Default Value | Description |
| - | - | - | - | - |
| serviceId | `vault` | true | | Open a Vault service|
| options.view | `service-connection` | true | | Assign to open service connection page|
| options.entityKey | string | true | | Service entity key <br /><br /><strong>NOTE:</strong> Top page of the Vault would be shown if `entityKey` is invalid.|

#### Open Vault Service Setting Page

It has to include these properties of `options` below when calling [openService](#openservice) API.

<strong>NOTE:</strong> This scenario only works when serviceId is `vault`.

<h6>Usage:</h6>

```javascript
mtLinkSdk.openService('vault', { view: 'connection-setting', credentialId: '123456'});
```

| Parameter | Type | Required | Default Value | Description |
| - | - | - | - | - |
| serviceId | `vault` | true | | Open a Vault service|
| options.view | `connection-setting` | true | | Assign to open connection setting page|
| options.credentialId | string | true | | Service credential Id <br /><br /><strong>NOTE:</strong> Top page of the Vault would be shown if the `credentialId` is invalid.|

#### Open Vault Customer Support Page

It has to include these properties of `options` below when calling [openService](#openservice) API.

<strong>NOTE:</strong> This scenario only works when serviceId is `vault`.

<h6>Usage:</h6>

```javascript
mtLinkSdk.openService('vault', { view: 'customer-support' });
```

| Parameter | Type | Required | Default Value | Description |
| - | - | - | - | - |
| serviceId | `vault` | true | | Open a Vault service|
| options.view | `customer-support` | true | | Assign to open customer support page|

### requestMagicLink

Expand Down
88 changes: 88 additions & 0 deletions src/api/__tests__/open-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,94 @@ describe('api', () => {
expect(open).toBeCalledWith(url, '_self');
});

test('vault/services-list', () => {
open.mockClear();

openService(new MtLinkSdk().storedOptions, 'vault', {
view: 'services-list',
type: 'bank',
group: 'grouping_testing',
search: 'vault',
showRememberMe: false,
});

expect(open).toBeCalledTimes(1);

const query = qs.stringify({
configs: generateConfigs({
showRememberMe: false,
}),
group: 'grouping_testing',
type: 'bank',
search: 'vault',
});
const url = `${VAULT_DOMAINS.production}/services?${query}`;

expect(open).toBeCalledWith(url, '_self');
});

test('vault/service-connection', () => {
open.mockClear();

openService(new MtLinkSdk().storedOptions, 'vault', {
view: 'service-connection',
entityKey: 'fauxbank_test_bank',
showRememberMe: false,
});

expect(open).toBeCalledTimes(1);

const query = qs.stringify({
configs: generateConfigs({
showRememberMe: false,
}),
});
const url = `${VAULT_DOMAINS.production}/service/fauxbank_test_bank?${query}`;

expect(open).toBeCalledWith(url, '_self');
});

test('vault/connection-setting', () => {
open.mockClear();

openService(new MtLinkSdk().storedOptions, 'vault', {
view: 'connection-setting',
credentialId: '123',
showRememberMe: false,
});

expect(open).toBeCalledTimes(1);

const query = qs.stringify({
configs: generateConfigs({
showRememberMe: false,
}),
});
const url = `${VAULT_DOMAINS.production}/connection/123?${query}`;

expect(open).toBeCalledWith(url, '_self');
});

test('vault/customer-support', () => {
open.mockClear();

openService(new MtLinkSdk().storedOptions, 'vault', {
view: 'customer-support',
showRememberMe: false,
});

expect(open).toBeCalledTimes(1);

const query = qs.stringify({
configs: generateConfigs({
showRememberMe: false,
}),
});
const url = `${VAULT_DOMAINS.production}/customer-support?${query}`;

expect(open).toBeCalledWith(url, '_self');
});

test('link-kit', () => {
open.mockClear();

Expand Down
98 changes: 86 additions & 12 deletions src/api/open-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,112 @@ import { stringify } from 'qs';

import { generateConfigs, mergeConfigs, getIsTabValue } from '../helper';
import { MY_ACCOUNT_DOMAINS, VAULT_DOMAINS, LINK_KIT_DOMAINS } from '../server-paths';
import { StoredOptions, ServiceId, ConfigsOptions } from '../typings';
import {
StoredOptions,
ServiceId,
OpenServicesConfigsOptions,
ConnectionSettingType,
ServiceConnectionType,
ServicesListType,
} from '../typings';

interface QueryData {
client_id?: string;
cobrand_client_id?: string;
locale?: string;
configs: string;
}

export default function openService(
storedOptions: StoredOptions,
serviceId: ServiceId,
options: ConfigsOptions = {}
options: OpenServicesConfigsOptions = {}
): void {
if (!window) {
throw new Error('[mt-link-sdk] `openService` only works in the browser.');
}

const { clientId, mode, cobrandClientId, locale } = storedOptions;
const { isNewTab, ...rest } = options;
const { isNewTab, view, ...rest } = options;

const getQueryValue = (needStringify = true): string | QueryData => {
const query: QueryData = {
client_id: clientId,
cobrand_client_id: cobrandClientId,
locale,
configs: generateConfigs(mergeConfigs(storedOptions, rest)),
};

const queryString = stringify({
client_id: clientId,
cobrand_client_id: cobrandClientId,
locale,
configs: generateConfigs(mergeConfigs(storedOptions, rest)),
});
if (!needStringify) {
return query;
}

return stringify(query);
};

switch (serviceId) {
case 'vault':
window.open(`${VAULT_DOMAINS[mode]}?${queryString}`, getIsTabValue(isNewTab));
if (!view) {
window.open(`${VAULT_DOMAINS[mode]}?${getQueryValue()}`, getIsTabValue(isNewTab));
break;
}

switch (view) {
case 'services-list':
// eslint-disable-next-line no-case-declarations
const { group, type, search } = options as ServicesListType;

window.open(
`${VAULT_DOMAINS[mode]}/services?${stringify({
...(getQueryValue(false) as QueryData),
group,
type,
search,
})}`,
getIsTabValue(isNewTab)
);
break;

case 'service-connection':
// eslint-disable-next-line no-case-declarations
const { entityKey } = options as ServiceConnectionType;

window.open(
`${VAULT_DOMAINS[mode]}/service/${entityKey}?${getQueryValue()}`,
getIsTabValue(isNewTab)
);
break;

case 'connection-setting':
// eslint-disable-next-line no-case-declarations
const { credentialId } = options as ConnectionSettingType;

window.open(
`${VAULT_DOMAINS[mode]}/connection/${credentialId}?${getQueryValue()}`,
getIsTabValue(isNewTab)
);
break;

case 'customer-support':
default:
window.open(
`${VAULT_DOMAINS[mode]}/customer-support?${getQueryValue()}`,
getIsTabValue(isNewTab)
);
break;
}

break;

case 'myaccount-settings':
window.open(`${MY_ACCOUNT_DOMAINS[mode]}/settings?${queryString}`, getIsTabValue(isNewTab));
window.open(
`${MY_ACCOUNT_DOMAINS[mode]}/settings?${getQueryValue()}`,
getIsTabValue(isNewTab)
);
break;

case 'link-kit':
window.open(`${LINK_KIT_DOMAINS[mode]}?${queryString}`, getIsTabValue(isNewTab));
window.open(`${LINK_KIT_DOMAINS[mode]}?${getQueryValue()}`, getIsTabValue(isNewTab));
break;

default:
Expand Down
13 changes: 12 additions & 1 deletion src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,19 @@ export function mergeConfigs(
export function generateConfigs(configs: ConfigsOptions = {}): string {
const snakeCaseConfigs: { [key: string]: string | AuthAction | boolean | undefined } = {};

const configKeys = [
'email',
'backTo',
'authAction',
'showAuthToggle',
'showRememberMe',
'isNewTab',
];

for (const key in configs) {
snakeCaseConfigs[snakeCase(key)] = configs[key as keyof ConfigsOptions];
if (configKeys.includes(key)) {
snakeCaseConfigs[snakeCase(key)] = configs[key as keyof ConfigsOptions];
}
}

return stringify({
Expand Down
32 changes: 32 additions & 0 deletions src/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,38 @@ export interface ConfigsOptions extends PrivateConfigsOptions {
isNewTab?: boolean;
}

export type ServicesListType = {
view?: 'services-list';
group?:
| 'grouping_bank'
| 'grouping_bank_credit_card'
| 'grouping_bank_dc_card'
| 'grouping_corporate_credit_card'
| 'grouping_credit_card'
| 'grouping_credit_coop'
| 'grouping_credit_union'
| 'grouping_dc_pension_plan'
| 'grouping_debit_card'
| 'grouping_digital_money'
| 'grouping_ja_bank'
| 'grouping_life_insurance'
| 'grouping_point'
| 'grouping_regional_bank'
| 'grouping_stock'
| 'grouping_testing';
type?: 'bank' | 'credit_card' | 'stored_value' | 'point' | 'corporate';
search?: string;
};

export type ServiceConnectionType = { view?: 'service-connection'; entityKey: string };

export type ConnectionSettingType = { view?: 'connection-setting'; credentialId: string };

export type CustomerSupportType = { view?: 'customer-support' };

export type OpenServicesConfigsOptions = ConfigsOptions &
(ServicesListType | ServiceConnectionType | ConnectionSettingType | CustomerSupportType);

export type Scopes = string | string[];

interface AuthorizeConfigsOptions {
Expand Down