diff --git a/docs/README.md b/docs/README.md
index 67330dc..3b1f2f4 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -202,6 +202,80 @@ mtLinkSdk.openService(serviceId, options);
| - | - | - | - | - |
| serviceId | `vault`, `myaccount-settings`, `link-kit` | true | | Open a service by Id, current supported services are:
`vault` - Manage your financial institution credentials.`myaccount-settings` - Manage your Moneytree account settings.`link-kit` - View all your financial data.
NOTE: 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:
[Open Vault Services Page](#open-vault-services-page)[Open Vault Service Connection Page](#open-vault-service-connection-page)[Open Vault Service Setting Page](#open-vault-service-setting-page)[Open Vault Customer Support Page](#open-vault-customer-support-page)
NOTE: 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.
+
+NOTE: This scenario only works when serviceId is `vault`.
+
+Usage:
+
+```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),
`credit_card` (personal credit card),
`stored_value` (electronic money), `point` (loyalty point),
`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.
+
+NOTE: This scenario only works when serviceId is `vault`.
+
+Usage:
+
+```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
NOTE: 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.
+
+NOTE: This scenario only works when serviceId is `vault`.
+
+Usage:
+
+```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
NOTE: 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.
+
+NOTE: This scenario only works when serviceId is `vault`.
+
+Usage:
+
+```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
diff --git a/src/api/__tests__/open-service.test.ts b/src/api/__tests__/open-service.test.ts
index 22ec716..4b70f40 100644
--- a/src/api/__tests__/open-service.test.ts
+++ b/src/api/__tests__/open-service.test.ts
@@ -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();
diff --git a/src/api/open-service.ts b/src/api/open-service.ts
index 83f3eb9..88c9fe3 100644
--- a/src/api/open-service.ts
+++ b/src/api/open-service.ts
@@ -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:
diff --git a/src/helper.ts b/src/helper.ts
index 0842800..93b70b4 100644
--- a/src/helper.ts
+++ b/src/helper.ts
@@ -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({
diff --git a/src/typings.ts b/src/typings.ts
index 2b87540..2a48c68 100644
--- a/src/typings.ts
+++ b/src/typings.ts
@@ -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 {