2022-04-18 16:54:53 +00:00
|
|
|
import * as plugins from './tink.plugins.js';
|
2022-02-18 11:55:56 +00:00
|
|
|
|
2022-04-18 16:54:53 +00:00
|
|
|
import { TinkAccount } from './tink.classes.tinkaccount.js';
|
|
|
|
import { TinkProviderConsent } from './tink.classes.tinkproviderconsent.js';
|
2022-08-23 14:56:59 +00:00
|
|
|
import { BankAccount } from './tink.classes.bankaccount.js';
|
2022-02-18 11:55:56 +00:00
|
|
|
|
|
|
|
export class TinkUser {
|
|
|
|
// STATIC
|
2022-02-19 12:15:59 +00:00
|
|
|
public static async createNewTinkUser(tinkAccountArg: TinkAccount, externalUserIdArg: string) {
|
|
|
|
const accessToken = await tinkAccountArg.getClientAccessTokenForScope('user:create');
|
|
|
|
const responseData: {
|
|
|
|
external_user_id: string;
|
|
|
|
user_id: string;
|
|
|
|
} = await tinkAccountArg.request({
|
2022-02-18 11:55:56 +00:00
|
|
|
urlArg: '/api/v1/user/create',
|
2022-02-19 00:34:07 +00:00
|
|
|
accessToken,
|
2022-02-18 11:55:56 +00:00
|
|
|
methodArg: 'POST',
|
|
|
|
payloadArg: {
|
2022-02-19 10:43:10 +00:00
|
|
|
external_user_id: externalUserIdArg,
|
|
|
|
market: 'DE',
|
|
|
|
locale: 'en_US',
|
|
|
|
},
|
2022-02-18 11:55:56 +00:00
|
|
|
});
|
|
|
|
|
2022-02-19 12:15:59 +00:00
|
|
|
const newTinkUser = await TinkUser.getTinkUser(tinkAccountArg, externalUserIdArg);
|
|
|
|
return newTinkUser;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async getTinkUser(tinkAccountArg: TinkAccount, externalUserIdArg: string) {
|
|
|
|
const authorizationCode = await tinkAccountArg.getUserAuthorizationCode(
|
|
|
|
externalUserIdArg,
|
|
|
|
tinkAccountArg.clientId,
|
|
|
|
'user:read'
|
|
|
|
);
|
|
|
|
const accessToken = await tinkAccountArg.getUserAccessToken(authorizationCode);
|
|
|
|
const responseData: {
|
|
|
|
appId: string;
|
|
|
|
created: string;
|
|
|
|
externalUserId: string;
|
|
|
|
flags: string[];
|
|
|
|
id: string;
|
|
|
|
nationalId: string;
|
|
|
|
profile: {
|
|
|
|
// cashbackEnabled: boolean; // deprecated
|
|
|
|
currency: string;
|
|
|
|
locale: string;
|
|
|
|
market: string;
|
|
|
|
notificationSettings: {
|
|
|
|
balance: boolean;
|
|
|
|
budget: boolean;
|
|
|
|
doubleCharge: boolean;
|
|
|
|
einvoices: boolean;
|
|
|
|
fraud: boolean;
|
|
|
|
income: boolean;
|
|
|
|
largeExpense: boolean;
|
|
|
|
leftToSpend: boolean;
|
|
|
|
loanUpdate: boolean;
|
|
|
|
summaryMonthly: boolean;
|
|
|
|
summaryWeekly: boolean;
|
|
|
|
transaction: boolean;
|
|
|
|
unusualAccount: boolean;
|
|
|
|
unusualCategory: boolean;
|
|
|
|
};
|
|
|
|
periodAdjustedDay: 25;
|
|
|
|
periodMode: 'MONTHLY_ADJUSTED' | 'MONTHLY';
|
|
|
|
timeZone: string;
|
|
|
|
};
|
|
|
|
// username: string; // not relevant
|
|
|
|
} = await tinkAccountArg.request({
|
|
|
|
urlArg: '/api/v1/user',
|
|
|
|
accessToken,
|
|
|
|
methodArg: 'GET',
|
|
|
|
payloadArg: null,
|
|
|
|
});
|
|
|
|
const newTinkUser = new TinkUser(tinkAccountArg, responseData.id, responseData.externalUserId);
|
2022-02-19 00:34:07 +00:00
|
|
|
return newTinkUser;
|
2022-02-18 11:55:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// INSTANCE
|
|
|
|
public tinkAccountRef: TinkAccount;
|
|
|
|
public tinkUserId: string;
|
|
|
|
public externalUserIdArg: string;
|
|
|
|
|
|
|
|
constructor(tinkAccountrefArg: TinkAccount, tinkUserIdArg: string, externalUserIdArg: string) {
|
|
|
|
this.tinkAccountRef = tinkAccountrefArg;
|
|
|
|
this.tinkUserId = tinkUserIdArg;
|
|
|
|
this.externalUserIdArg = externalUserIdArg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* deletes the user
|
|
|
|
*/
|
|
|
|
public async delete() {
|
2022-02-19 10:43:10 +00:00
|
|
|
const authorizationCode = await this.tinkAccountRef.getUserAuthorizationCode(
|
|
|
|
this.externalUserIdArg,
|
|
|
|
this.tinkAccountRef.clientId,
|
|
|
|
'user:delete'
|
|
|
|
);
|
2022-02-19 00:34:07 +00:00
|
|
|
const accessToken = await this.tinkAccountRef.getUserAccessToken(authorizationCode);
|
2022-02-18 11:55:56 +00:00
|
|
|
const response = await this.tinkAccountRef.request({
|
|
|
|
methodArg: 'POST',
|
2022-02-19 00:34:07 +00:00
|
|
|
accessToken,
|
2022-02-18 11:55:56 +00:00
|
|
|
payloadArg: {},
|
2022-02-19 10:43:10 +00:00
|
|
|
urlArg: '/api/v1/user/delete',
|
2022-02-18 11:55:56 +00:00
|
|
|
});
|
2022-02-19 00:34:07 +00:00
|
|
|
console.log(`successfully deleted user with externalId ${this.externalUserIdArg}`);
|
2022-02-18 11:55:56 +00:00
|
|
|
}
|
2022-02-19 10:43:10 +00:00
|
|
|
|
2022-02-19 12:15:59 +00:00
|
|
|
/**
|
|
|
|
* gets a tink link that can be used by a user to connect accounts
|
|
|
|
* @returns
|
|
|
|
*/
|
2022-05-12 14:42:36 +00:00
|
|
|
public async getTinkLinkForMarket(linkOptionsArg: {
|
|
|
|
countryId: string;
|
|
|
|
redirectUrl: string;
|
2022-08-23 14:56:59 +00:00
|
|
|
/**
|
|
|
|
* an optional state that is transported through to the callback
|
|
|
|
*/
|
|
|
|
customState: string;
|
2022-05-12 14:42:36 +00:00
|
|
|
testProviderBool?: boolean;
|
|
|
|
} = {
|
2022-10-29 14:18:29 +00:00
|
|
|
countryId: 'NL',
|
2022-05-12 14:42:36 +00:00
|
|
|
redirectUrl: 'https://console.tink.com/callback',
|
2022-08-23 14:56:59 +00:00
|
|
|
customState: "exampleState",
|
2022-05-12 14:42:36 +00:00
|
|
|
testProviderBool: true
|
|
|
|
}): Promise<string> {
|
|
|
|
if (typeof linkOptionsArg.testProviderBool !== 'boolean') {
|
|
|
|
linkOptionsArg.testProviderBool = false;
|
|
|
|
}
|
2022-02-19 10:43:10 +00:00
|
|
|
const authorizationCode = await this.tinkAccountRef.getUserAuthorizationCode(
|
|
|
|
this.externalUserIdArg,
|
|
|
|
'df05e4b379934cd09963197cc855bfe9', // this is a hardcoded app id for tink link, as recommended by tink.com
|
|
|
|
'authorization:read,authorization:grant,credentials:refresh,credentials:read,credentials:write,providers:read,user:read'
|
|
|
|
);
|
2022-08-23 14:56:59 +00:00
|
|
|
const tinkUrlOptions: {[key: string]: string} = {}
|
|
|
|
tinkUrlOptions['client_id'] = this.tinkAccountRef.clientId;
|
|
|
|
tinkUrlOptions['redirect_uri']= linkOptionsArg.redirectUrl;
|
|
|
|
tinkUrlOptions['authorization_code'] = authorizationCode;
|
|
|
|
tinkUrlOptions['market'] = linkOptionsArg.countryId;
|
|
|
|
if (linkOptionsArg.testProviderBool) {
|
|
|
|
tinkUrlOptions['test'] = 'true';
|
|
|
|
}
|
|
|
|
if (linkOptionsArg.customState) {
|
|
|
|
tinkUrlOptions['state'] = linkOptionsArg.customState;
|
|
|
|
}
|
|
|
|
const url = plugins.smarturl.Smarturl.createFromUrl('https://link.tink.com/1.0/business-transactions/connect-accounts', {
|
|
|
|
searchParams: tinkUrlOptions
|
|
|
|
});
|
|
|
|
const tinkLinkUrl = url.toString();
|
2022-02-19 10:43:10 +00:00
|
|
|
return tinkLinkUrl;
|
|
|
|
}
|
2022-02-19 12:15:59 +00:00
|
|
|
|
|
|
|
public async getProviderConsents(): Promise<TinkProviderConsent[]> {
|
|
|
|
const providerConsents: TinkProviderConsent[] =
|
|
|
|
await TinkProviderConsent.getProviderConsentsForUser(this);
|
|
|
|
return providerConsents;
|
|
|
|
}
|
2022-08-23 14:56:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gets all accounts
|
|
|
|
*/
|
|
|
|
public async getAllBankAccounts() {
|
|
|
|
const bankAccounts = await BankAccount.getBankAccountsForUser(this);
|
|
|
|
return bankAccounts;
|
|
|
|
}
|
2022-02-19 10:43:10 +00:00
|
|
|
}
|