fintecture-client
Advanced tools
Comparing version 1.0.12 to 1.0.13
import { AIS } from './src/Ais'; | ||
import { Authentication } from './src/Authentication'; | ||
import { IConfig } from './src/interfaces/ConfigInterface' | ||
import { IFintectureConfig } from './src/interfaces/ConfigInterface' | ||
import { IConnect } from './src/interfaces/connect/ConnectInterface' | ||
@@ -18,3 +18,3 @@ | ||
private config: IConfig; | ||
private config: IFintectureConfig; | ||
private connect: Connect; | ||
@@ -49,4 +49,4 @@ private resources: Resources; | ||
public async getProviders(options?: object): Promise<object> { | ||
return this.resources.providers(options); | ||
public async getProviders(search?: object): Promise<object> { | ||
return this.resources.providers(search); | ||
} | ||
@@ -58,4 +58,4 @@ | ||
public async getTestAccounts(options?: object): Promise<object> { | ||
return this.resources.testAccounts(options); | ||
public async getTestAccounts(search?: object): Promise<object> { | ||
return this.resources.testAccounts(search); | ||
} | ||
@@ -75,12 +75,12 @@ | ||
public async getAccounts(accessToken: string, customerId: string, options?: any): Promise<object> { | ||
return this.ais.getAccounts(accessToken, customerId, options); | ||
public async getAccounts(accessToken: string, customerId: string, search?: any, headers?: any): Promise<object> { | ||
return this.ais.getAccounts(accessToken, customerId, search, headers); | ||
} | ||
public async getTransactions(accessToken: string, customerId: string, accountId, options?: any): Promise<object> { | ||
return this.ais.getTransactions(accessToken, customerId, accountId, options); | ||
public async getTransactions(accessToken: string, customerId: string, accountId, search?: any, headers?: any): Promise<object> { | ||
return this.ais.getTransactions(accessToken, customerId, accountId, search, headers); | ||
} | ||
public async getAccountHolders(accessToken: string, customerId: string, options?: any): Promise<object> { | ||
return this.ais.getAccountHolders(accessToken, customerId, options); | ||
public async getAccountHolders(accessToken: string, customerId: string, search?: any, headers?: any): Promise<object> { | ||
return this.ais.getAccountHolders(accessToken, customerId, search, headers); | ||
} | ||
@@ -108,6 +108,2 @@ | ||
public verifyConnectUrlParameters(queryString): boolean { | ||
return this.connect.verifyUrlParameters(queryString); | ||
} | ||
private _validateConfigIntegrity(config) { | ||
@@ -122,3 +118,3 @@ if (!config.app_id) { | ||
if (!config.private_key && config.env === Constants.PRODUCTIONENVIRONMENT) { | ||
if (!config.private_key) { | ||
throw Error('private_key must be a string'); | ||
@@ -147,5 +143,5 @@ } | ||
return config as IConfig; | ||
return config as IFintectureConfig; | ||
} | ||
} |
@@ -22,11 +22,11 @@ import { IConnect } from './src/interfaces/connect/ConnectInterface'; | ||
refreshAccessToken(refreshToken: string): Promise<object>; | ||
getProviders(options?: object): Promise<object>; | ||
getProviders(search?: object): Promise<object>; | ||
getApplication(): Promise<object>; | ||
getTestAccounts(options?: object): Promise<object>; | ||
getTestAccounts(search?: object): Promise<object>; | ||
getRedirectAuthUrl(accessToken: string, providerId: string, redirectUri: string, state?: string): Promise<object>; | ||
getDecoupledAuthUrl(accessToken: string, providerId: string, psuId: string, psuIpAddress: any): Promise<object>; | ||
getDecoupledAuthStatus(accessToken: string, providerId: string, pollingId: string): Promise<object>; | ||
getAccounts(accessToken: string, customerId: string, options?: any): Promise<object>; | ||
getTransactions(accessToken: string, customerId: string, accountId: any, options?: any): Promise<object>; | ||
getAccountHolders(accessToken: string, customerId: string, options?: any): Promise<object>; | ||
getAccounts(accessToken: string, customerId: string, search?: any, headers?: any): Promise<object>; | ||
getTransactions(accessToken: string, customerId: string, accountId: any, search?: any, headers?: any): Promise<object>; | ||
getAccountHolders(accessToken: string, customerId: string, search?: any, headers?: any): Promise<object>; | ||
preparePayment(accessToken: string, payload: any): Promise<object>; | ||
@@ -37,4 +37,3 @@ paymentInitiate(accessToken: string, providerId: string, payload: any, redirectUri: string, state?: string): Promise<object>; | ||
getPisConnect(accessToken: string, connectConfig: any): Promise<IConnect>; | ||
verifyConnectUrlParameters(queryString: any): boolean; | ||
private _validateConfigIntegrity; | ||
} |
@@ -47,5 +47,5 @@ "use strict"; | ||
} | ||
getProviders(options) { | ||
getProviders(search) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.resources.providers(options); | ||
return this.resources.providers(search); | ||
}); | ||
@@ -58,5 +58,5 @@ } | ||
} | ||
getTestAccounts(options) { | ||
getTestAccounts(search) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.resources.testAccounts(options); | ||
return this.resources.testAccounts(search); | ||
}); | ||
@@ -79,15 +79,15 @@ } | ||
} | ||
getAccounts(accessToken, customerId, options) { | ||
getAccounts(accessToken, customerId, search, headers) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.ais.getAccounts(accessToken, customerId, options); | ||
return this.ais.getAccounts(accessToken, customerId, search, headers); | ||
}); | ||
} | ||
getTransactions(accessToken, customerId, accountId, options) { | ||
getTransactions(accessToken, customerId, accountId, search, headers) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.ais.getTransactions(accessToken, customerId, accountId, options); | ||
return this.ais.getTransactions(accessToken, customerId, accountId, search, headers); | ||
}); | ||
} | ||
getAccountHolders(accessToken, customerId, options) { | ||
getAccountHolders(accessToken, customerId, search, headers) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.ais.getAccountHolders(accessToken, customerId, options); | ||
return this.ais.getAccountHolders(accessToken, customerId, search, headers); | ||
}); | ||
@@ -120,5 +120,2 @@ } | ||
} | ||
verifyConnectUrlParameters(queryString) { | ||
return this.connect.verifyUrlParameters(queryString); | ||
} | ||
_validateConfigIntegrity(config) { | ||
@@ -131,3 +128,3 @@ if (!config.app_id) { | ||
} | ||
if (!config.private_key && config.env === Constants_1.Constants.PRODUCTIONENVIRONMENT) { | ||
if (!config.private_key) { | ||
throw Error('private_key must be a string'); | ||
@@ -134,0 +131,0 @@ } |
{ | ||
"name": "fintecture-client", | ||
"version": "1.0.12", | ||
"version": "1.0.13", | ||
"description": "Fintecture Open Banking API Gateway enabling secure bank connections and payments", | ||
@@ -5,0 +5,0 @@ "main": "lib/fintecture-client.js", |
@@ -24,3 +24,3 @@ "use strict"; | ||
describe(`AIS - get fintecture access token - `, () => { | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking }); | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking, private_key: config_1.TestConfig.appPrivKeyOpenbanking }); | ||
const redirectUri = config_1.TestConfig.appRedirectUri; | ||
@@ -54,2 +54,10 @@ let accessToken; | ||
let account; | ||
it(`get provider ${providerId} AIS account with PSU IP`, (done) => __awaiter(void 0, void 0, void 0, function* () { | ||
const filters = null; | ||
const extras = { 'x-psu-ip-address': '172.0.0.1' }; | ||
const accounts = yield client.getAccounts(accessToken, customerId, filters, extras); | ||
account = accounts.data[0].id; | ||
expect(accounts.data.length).toBeGreaterThan(0); | ||
done(); | ||
})); | ||
it(`get provider ${providerId} AIS account `, (done) => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -66,4 +74,11 @@ const accounts = yield client.getAccounts(accessToken, customerId); | ||
})); | ||
it(`get provider ${providerId} AIS auth URL with app_id with PSU IP`, (done) => __awaiter(void 0, void 0, void 0, function* () { | ||
const filters = null; | ||
const extras = { 'x-psu-ip-address': '172.0.0.1' }; | ||
const transactions = yield client.getTransactions(accessToken, customerId, account, filters, extras); | ||
expect(transactions.data.length).toBeGreaterThan(0); | ||
done(); | ||
})); | ||
}); | ||
}); | ||
//# sourceMappingURL=ais.spec.js.map |
@@ -24,4 +24,3 @@ "use strict"; | ||
const state = 'somestate'; | ||
const clientOBanking = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking }); | ||
const clientMerchant = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdMerchant, app_secret: config_1.TestConfig.appSecretMerchant }); | ||
const clientOBanking = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking, private_key: config_1.TestConfig.appPrivKeyOpenbanking }); | ||
beforeEach(() => { | ||
@@ -28,0 +27,0 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; |
@@ -11,15 +11,3 @@ "use strict"; | ||
}; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const crypto = __importStar(require("crypto")); | ||
const qs_1 = __importDefault(require("qs")); | ||
const fintecture_client_1 = require("../fintecture-client"); | ||
@@ -49,3 +37,3 @@ const BaseUrls_1 = require("./../src/utils/URLBuilders/BaseUrls"); | ||
it('#PIS getPisConnect', (done) => __awaiter(void 0, void 0, void 0, function* () { | ||
const mockConnectUrl = BaseUrls_1.BaseUrls.FINTECTURECONNECTURL_SBX + '/pis?state='; | ||
const mockConnectUrl = BaseUrls_1.BaseUrls.FINTECTURECONNECTURL_SBX + '/pis?config='; | ||
const tokens = yield client.getAccessToken(); | ||
@@ -99,130 +87,3 @@ const connectMin = yield client.getPisConnect(tokens.access_token, connectConfigMin); | ||
})); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) true', () => { | ||
const parameters = { | ||
s: undefined, | ||
session_id: 'session_id', | ||
status: 'status', | ||
customer_id: 'customer_id', | ||
provider: 'provider', | ||
state: 'state' | ||
}; | ||
// Generate encrypted | ||
const plainText = qs_1.default.stringify({ | ||
app_id: config_1.TestConfig.appIdMerchant, | ||
app_secret: config_1.TestConfig.appSecretMerchant, | ||
session_id: parameters.session_id, | ||
status: parameters.status, | ||
customer_id: parameters.customer_id, | ||
provider: parameters.provider, | ||
state: parameters.state | ||
}); | ||
const digest = crypto.createHash('sha256').update(plainText).digest('base64'); | ||
// RSA based public key encryption (max 245 bytes) | ||
const key = { | ||
key: config_1.TestConfig.appPubKeyMerchant, | ||
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING | ||
}; | ||
const message = Buffer.from(digest); | ||
const encrypted = crypto.publicEncrypt(key, message).toString("base64"); | ||
parameters.s = encrypted; | ||
const response = client.verifyConnectUrlParameters(parameters); | ||
expect(response).toBe(true); | ||
}); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) false', () => { | ||
const parameters = { | ||
s: undefined, | ||
session_id: 'session_id', | ||
status: 'status', | ||
customer_id: 'customer_id', | ||
provider: 'provider', | ||
state: 'state' | ||
}; | ||
// Generate encrypted | ||
const plainText = qs_1.default.stringify({ | ||
app_id: 'other_app_id', | ||
app_secret: config_1.TestConfig.appSecretMerchant, | ||
session_id: parameters.session_id, | ||
status: parameters.status, | ||
customer_id: parameters.customer_id, | ||
provider: parameters.provider, | ||
state: parameters.state | ||
}); | ||
const digest = crypto.createHash('sha256').update(plainText).digest('base64'); | ||
// RSA based public key encryption (max 245 bytes) | ||
const key = { | ||
key: config_1.TestConfig.appPubKeyMerchant, | ||
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING | ||
}; | ||
const message = Buffer.from(digest); | ||
const encrypted = crypto.publicEncrypt(key, message).toString("base64"); | ||
parameters.s = encrypted; | ||
const response = client.verifyConnectUrlParameters(parameters); | ||
expect(response).toBe(false); | ||
}); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) invalid param type', () => { | ||
expect(() => { | ||
client.verifyConnectUrlParameters('param'); | ||
}).toThrow(new Error("invalid parameter format, the parameter must be an object instead a string")); | ||
}); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) Error no digest', () => { | ||
const parameters = { | ||
session_id: 'session_id', | ||
status: 'status', | ||
customer_id: 'customer_id', | ||
provider: 'provider', | ||
state: 'state' | ||
}; | ||
expect(() => { | ||
client.verifyConnectUrlParameters(parameters); | ||
}).toThrow(new Error("missing query string")); | ||
}); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) Error no session_id', () => { | ||
const parameters = { | ||
s: 'test_digest', | ||
status: 'status', | ||
customer_id: 'customer_id', | ||
provider: 'provider', | ||
state: 'state' | ||
}; | ||
expect(() => { | ||
client.verifyConnectUrlParameters(parameters); | ||
}).toThrow(new Error("missing query string")); | ||
}); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) Error no status', () => { | ||
const parameters = { | ||
s: 'test_digest', | ||
session_id: 'session_id', | ||
customer_id: 'customer_id', | ||
provider: 'provider', | ||
state: 'state' | ||
}; | ||
expect(() => { | ||
client.verifyConnectUrlParameters(parameters); | ||
}).toThrow(new Error("missing query string")); | ||
}); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) Error no customer_id', () => { | ||
const parameters = { | ||
s: 'test_digest', | ||
session_id: 'session_id', | ||
status: 'status', | ||
provider: 'provider', | ||
state: 'state' | ||
}; | ||
expect(() => { | ||
client.verifyConnectUrlParameters(parameters); | ||
}).toThrow(new Error("missing query string")); | ||
}); | ||
it('#verifyUrlParameters(connectConfig, parameters, privateKey) Error no provider', () => { | ||
const parameters = { | ||
s: 'test_digest', | ||
session_id: 'session_id', | ||
status: 'status', | ||
customer_id: 'customer_id', | ||
state: 'state' | ||
}; | ||
expect(() => { | ||
client.verifyConnectUrlParameters(parameters); | ||
}).toThrow(new Error("missing query string")); | ||
}); | ||
}); | ||
//# sourceMappingURL=connect.spec.js.map |
@@ -9,2 +9,3 @@ /** | ||
static readonly appSecretOpenbanking: string; | ||
static readonly appPrivKeyOpenbanking: string; | ||
static readonly appRedirectUri: string; | ||
@@ -14,3 +15,2 @@ static readonly appIdMerchant: string; | ||
static readonly appPrivKeyMerchant: string; | ||
static readonly appPubKeyMerchant: string; | ||
} |
@@ -11,44 +11,63 @@ "use strict"; | ||
exports.TestConfig = TestConfig; | ||
TestConfig.appIdOpenbanking = '3f12a5c0-f719-4c14-9eac-08ed99290109'; | ||
TestConfig.appSecretOpenbanking = '93ea0128-8258-4b1d-9109-b4899a98677b'; | ||
TestConfig.appIdOpenbanking = '8687cc56-22be-4ef3-946f-4b52b83008b0'; | ||
TestConfig.appSecretOpenbanking = '7f493c9a-f512-48d7-849d-29a1a6ad73ea'; | ||
TestConfig.appPrivKeyOpenbanking = `-----BEGIN PRIVATE KEY----- | ||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCe6S+EFcQGpKKD | ||
Kyk5jr0OUED6uuK9rnadkPHq6WkFUIIEZ+xjcL9HHIRVzI/PTWvb6SWc7pqXNAht | ||
GQL43JKjqh5Itm4ml9Rrs08UeEBmo1K4pCQGXGn9UqLHfIGpHznlhwhq2BUV3HaU | ||
OZ+LKNuCaHdRXnky7i8+6kvwzTuMFHZcHW6WKiFxxm5Y8cXfeB3bCuAkzrpa3dOG | ||
qQfxm03YIG5XKHs+77gN/AfnCSOQ0mSOl9uIV0ulKWWlV2/+BFmhYSfogXnD1kdF | ||
TIwXiIzUdhRiG9xdLpP+e/Dt/LLsHjN7iYfzNiGkEt45GNHHtVqMH5MvyKzsK70n | ||
RJg86h/9AgMBAAECggEAIZjrkuGHMGBee50EekbTcdNF6bzZc4EPUwDyJNh0e8sp | ||
sgTG1b9gsYg18m3tecbEpxoD+cn4pT87CNXg6vy3hCLThEwNvdsb7ila7tj9xLWD | ||
J8aMV0vynLx77fFE+JzBgOWrwestihGygGQudx2MS2YK1AlFVp9FHegrZh3+GP9l | ||
K9D1VoaufeWUmyp6ez4bikeJgvBLwKo8FvAt59ELvhglClwGWjuB+o8X9nKaxc2/ | ||
CIEW3WZSRZdj6oRkC+F+Fb3AnMdGAdF5UczkyVW374wamhmxmhztMGL1uLSgU1ZL | ||
JRpWCwGODNf2HA81VVGEwXXisqWy9oxGieWy/GlsAQKBgQDR6/HmOrtqhcZ4OqIv | ||
SzG1dme3mZ1FUPLMJSVWu9nV+y3YsJogXZCOktn/htTGrWCV7Wa3J27gSnfpMO0T | ||
sKY8xzLil6axGRD1OCMh/4+AW8fi1okYghPgJQlgXwhKCF6+u/up3ocIEtHS4uIO | ||
ffDsT5bGYexzHNXjyI22YfEb2QKBgQDBys9HxoR/QyFRvoys8KSVK9Kujtrd9pe5 | ||
6K2UY0yiviHTF3XOWVsX7YPVbZuCRpzgi+fXjB6FvT/LpL4LmFnKPiys4Y8OQ3bH | ||
DaNhZ+O9vcdtvEUZN6h2HbssIWMY7WF6vtyXCQPF8FSAB3udXb4JYLKzOU7R0uWS | ||
A3CVjGgCxQKBgBQzs7TnZA/tTdtWMTOB9geznGmj4+m+z47r6Dr/mwgnwxK+dCa3 | ||
OmkuIsKflCyGlOv4y9DGf7ogEIgliDtD3cutk+0QkR8r/WDMBT2JXaMJsiPXZ5wv | ||
MIB6r/tRSfft9EhAyQhg/Pe+7+huozin0B69zhHLbLjrRn5EV7b8l/qJAoGAHpD/ | ||
qsGMKoqLGdqlU63NN94mp/POX85CVkd2AX68GrtEmIgNw9NiQ97puWNFcQH0QpKu | ||
qdfnBI86HcPJWgjYuMafw1D8gHJxrKnhCD8bs9TYPN3CRFz8DE1aNXa6q7bddj/e | ||
iVAZsUHcAimr/MFJdS80YIJ8hSnvnd0/B8eSrEUCgYAH60rW0KV+w5N52z/OBEfn | ||
lVy/uQC4ge1dAYhcvxMNNCJ2mszxP5hW5LqCrkHj+9SULrHxvkYZHSKGcMVpiEq8 | ||
IH5SfaI3mb4YDzgCMjdhj8G5m+yUZ+UKncPcQ0+iRT8O2IqQp2c1Ut9qBuSJZh43 | ||
HoxR9hrXXccObKIbRBb1zA== | ||
-----END PRIVATE KEY-----`; | ||
TestConfig.appRedirectUri = 'https://www.fintecture.com'; | ||
TestConfig.appIdMerchant = '1b96c253-1944-4986-a467-df2152ddffdb'; | ||
TestConfig.appSecretMerchant = 'f03fec5f-4d38-437f-914d-817337550fab'; | ||
TestConfig.appIdMerchant = 'e02a94ed-ca47-4ece-b641-82d2bf658288'; | ||
TestConfig.appSecretMerchant = '7ad7b202-dc68-4cd2-ae05-4d338316972d'; | ||
TestConfig.appPrivKeyMerchant = `-----BEGIN PRIVATE KEY----- | ||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCeEocGuXp9AA+H | ||
/8o2exRRkCsU49h8COUuCtjHJgEL4Wz9mKb1tZ7w9yzBYZ+vyOSMbMFocvIHZQac | ||
up1cYX6+5J/XcH8QDJRqfq/dr//3xMwYH+xFBVL8R6C6Hoie3sow4x1k+ihOIZ+Q | ||
MOoDTR+dSPnWrYjzKLa6rESJHlBrzQ5Qgq8KnwmiInkTMZq1fyOY0fBTdJuikr7/ | ||
xEnQBl44P/gqQzEeiS6kOswoXVn5DhQUSyQSMfTmrhuswnc/Ud5faBbQz1ZegsNc | ||
eY6S6/b89lI4vcj6SCubuDWUEIVongvijF14p/y/UIU0y1JtQsK/5tmtSNboCnNN | ||
kuKA079zAgMBAAECggEAI14i3xLOALzsPLIzROhZ/fvjX8uxCuOUn64mnbx3nHhm | ||
QgGPTcfC1ciAN46Hw7WPyYml5qBdXeExTw0EG4Dm8oBF8VbG30jpRkCtSc1Q2Nes | ||
ELPH0hOkYzUFlc8yI1XW6IRQdeDw9rZYNNN08KMncTI8UFfInhtccz0LIqDpPo0r | ||
T/LVe3hN6tyW48VThMhTbf7vOGg1+fxABu8uoKFFq8bs/rp5b3Cu/8nfyNksEaTg | ||
kz8z5dWTS0BCTMBPjgWMRXiRghWkYwQX84EVjapuPQnsEaH8zKOemITviBlO6wfh | ||
iD2wyVwNfLTwaBiixzxh3uZGti0wq4Hg0g/31MAWDQKBgQDRlH+Mr+5zzIuSBOKj | ||
MvIqNli9W2n7yKzpGjQTTG4V2EOwE2vxY3fbB4oxNVRNa4B44YM19P7B7gwLiWnO | ||
eEuC95pS+vYNcYvCUyAxBEBlBTKKV7VMuavPjNkLgQH9F4Dj/reKsXcqbOzxR/5n | ||
VjNYgaNWXb4fUYNrqyUuWV0bTQKBgQDBFXdSC4maU7MRMahkWhf/70S0917c4csx | ||
pUut43gMpjFBDQMnXERXQudqFGPlEvzs5HMLl373SMZHiHr8WDcRwdtHMGTJOVqj | ||
pD0XONzkP9jrwUIOKrF65VIFj005maFpAeHG5ZakIZ7WjdXQxh7j06SqoK5caJOK | ||
rXl/qXNlvwKBgHc5RP4hr0LM37Enek5g0wZUeFLwR/BmDodk0q8P0ag3qPnncoaV | ||
kT9WoLSxo82PFDyv/Vaakrp70vpVJ42/PSW5+V6vSX4IU/suEqgPxRoyxLeSgZ6u | ||
GSEu/OHgd+Mklbwd0QfjQOkvofL4g68BiKAWz3Z4SYnDc0Gy0Kn3SFIZAoGBAIuk | ||
oMVfvsc0nZ9j0KuzVQQu4fwXpC4Px0tChvdeOia704d+h7dhzbNmmcNot86m6vHR | ||
Tzsk+BiUM4LsvDXg/wMCtzpHT70Qk/MiB2TSJT+WxaXMAaAJVI7TZ3zJ5UoxSEGP | ||
sOCOj2JpRl1Z+zeg8hpHqSIWT8RZhcuYJvUjcmg1AoGADluBhTWky1K+QwmQE0DO | ||
OHkL0TyG6qQ/31nnuLW5Ej1xQtuElQVWj/KZK5AJrusXSUEUzqPMR7MvMSclURyV | ||
Mqo3BZADRlcr0AKP2TYSBCNcEBmBHCI9GfIRCPFR1eK+IciRyqjcz7kYlZ0YyfjF | ||
r3xIiGe3JhVHqyTRE+maKu0= | ||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMTItyD1NiVhMu | ||
LVfy9Bh7bTBbXwGN054wERgzdJOxdOYHdM6uMtds41HnS+nyXmLgZLUg4PvJSo+Y | ||
nUxjcQNwyh38tFw9Qa6hHw+UlbYX3zyaY2tVUyzYgYxrt3fFctoYRu0c+2+z5BV3 | ||
ZGDj+/kbDwnZhKpzvK5lVclbFRB07TYg8Oejx9Cag4iCdz27pwIWYmCGsK6WgIkb | ||
0Ule5Nt/iPol4u/Ls6oWfsVbvR4HM/CM/DEZmWmFoLTeWgH+ATJr+j1pG/AmW95/ | ||
DAfe1dK5QEc5V41+CVlUrDd4GtcMnA7nJKN0kxD3foiwTHPHF03BbS9gAKr/jcEP | ||
DWLDemqDAgMBAAECggEAG8bafMcNqMSYNgKPPyal/34QgZPQw8Y+bz2bwz8553pD | ||
3kao5TFfbdwYYjDFnaDso6K9p7s/MJaVIIRegvS2KYspeZbSJbf89MYi2apjSCqf | ||
dERJLyAwbD1s6KZYv/1GHt/h1DtxbA16R7HbpJO5Qk8QoUTy4eqI8Zkw19Ps2WC6 | ||
wfC5KNzZUaWD/in7LMcF4LhfYVOZmFjysDLxoDTnntjfvil6FmmSMhzgFLQ/tJkY | ||
Qe0gyl+UzYsKZM6LxJVucocfAmLNaOEnvpbry6bkrnghGuBH3z/XcwHXr4cTwDkZ | ||
DCm03/BnT+/AuyjPTGTF4flMaihlvqW9weRZ5ySMlQKBgQD4R+1X/5eWvFQubKPo | ||
iyM/KI8hjSMoBsM8XEKbqw7t78QISM0uyB7gXul/vzetK3stpkwcA5EF58jM75gW | ||
jwBZ7QmjoStU3E/Hk6QdghYJx6NRNeBPIroud4MD0ouP3h6A8QQMWA8Ll3WqXIkj | ||
+uBHP1dMjQvIhFQGgB54x3c1HQKBgQDSppB3GnSvTXJ9gR53fGKlPmfzSzu0VILR | ||
jJYU4er9/O3/YU8mTij9RKG4i0m+AM3AuzycExshZ4ToCZ82JIPA8+JKwi9UlEFd | ||
tB/Vt7QRXLIiCtae3EIloAAcse9QoAz7ZsVbSoEyvqB1Ui59oX28m2uXXZW/Ytzc | ||
fByk2HIsHwKBgQC3cjW86l3wAxDUCHOHM58EYIx5BtZuEakZpTWV3Ws3hQu770aj | ||
hTvDHn26ZOfXbKQj05aysDPsQBlOysz+BgUFbK3NmBzzI6FS3hTJtL9h1H8oVv14 | ||
mzkjcix8m4mA8GZrcSlDkaD0OKG5EYxG6GvkWLnBFwoYyyVmdC2PohnDRQKBgQDE | ||
wxDuL6gOlyj6UkFDGsyJzWELwJpkNwx67/bASsZVuIwWn65u+VMQP6tP1ctrzxRh | ||
koNqxe3xpeBfXZ151WG8OhKGAhxzxIfKHxYdaxqnnQ5G/hi7CsI+otV3+Dyx8s4t | ||
hjGStGU6IRWAgOMsNkxcgFBfcusNeisTSFr5H7SFwQKBgC4CjsKoosi3K6PfNWom | ||
E2ZzGuAC+wosigEjivGBAX5SBRunYXle+l2qEugZQMQbCupxrmPsAQEq7yFXGVh/ | ||
he+7PoGeuN+tyU97ysJVpQrjvc29PdhKt4rGpby7c9omr4xlgtYUJo6KXZO1N3g+ | ||
NGIDKuWDm34+VDzlhcjMC5sz | ||
-----END PRIVATE KEY-----`; | ||
TestConfig.appPubKeyMerchant = `-----BEGIN PUBLIC KEY----- | ||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnhKHBrl6fQAPh//KNnsU | ||
UZArFOPYfAjlLgrYxyYBC+Fs/Zim9bWe8PcswWGfr8jkjGzBaHLyB2UGnLqdXGF+ | ||
vuSf13B/EAyUan6v3a//98TMGB/sRQVS/Eeguh6Int7KMOMdZPooTiGfkDDqA00f | ||
nUj51q2I8yi2uqxEiR5Qa80OUIKvCp8JoiJ5EzGatX8jmNHwU3SbopK+/8RJ0AZe | ||
OD/4KkMxHokupDrMKF1Z+Q4UFEskEjH05q4brMJ3P1HeX2gW0M9WXoLDXHmOkuv2 | ||
/PZSOL3I+kgrm7g1lBCFaJ4L4oxdeKf8v1CFNMtSbULCv+bZrUjW6ApzTZLigNO/ | ||
cwIDAQAB | ||
-----END PUBLIC KEY-----`; | ||
//# sourceMappingURL=config.js.map |
@@ -10,6 +10,5 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const crypto = __importStar(require("crypto")); | ||
const UtilsCrypto = __importStar(require("../src/utils/Crypto")); | ||
const config_1 = require("./constants/config"); | ||
const mockSignature = "QVEX1W0EGwsTWGAwdNmh1pY/p/QIaw2Owz/jRuQpvmwl+FN84+fLwZUs8Ts3BYbkON5xaVv3UA/eqO+6JfOfCg4IUSMNzgDK0Ibpy02eqz8WMtSUHjto9D35RbzqxbBhL/UNK0igqkv+fqxzBYsjEJi5UQX1CXyV+Bn6vHQCkLqqYiitxWy8BtdJ+W2YChb74eyhZzmdGfTfwUO5H3OlhSGcRubclkO+yeL6gIr/XWGIfuT9jtK2UYzLffLelIDc9mxBFuhXdl+3iddm/YkYb2pxayZKgXtnzRYsiz1GhlWoMcbNdToNauGuIe0aeYAX77BlLY4P4IT7got224sLig=="; | ||
const mockSignature = "dJcMjG/HsJoq2x/PoZ8YfFzzMFFyfWpqiDnODIOiZ5k9GqmkwrPVJ1fflZLVBD/h1dleIDFJPWAwvBj8VsWCjEEjbvujKV32EJjDFiw3CACvRbx1IYr0JtjorKsjDABlJNbj+LBSEk1YGRDbKYBqURo4CL/xMOAHlZ856kr4fkNH4rlJ9c+kq4KrvMEcZQc6EfN37p2Ap6pjLm9abwH3a+cQNjOGI07/3QY1spfj7Z89svVEHEc9XSSTcM5aE18F4C7ACtEXsGYZMUSRS7/JfE6Ma3gsnKbKUPwhsQjhmrWhsFlqpQ4mcJ+eJWj1eSA7H97QoN5MKaAtDxHYHQyVog=="; | ||
const payload = { payment: 'payment' }; | ||
@@ -53,26 +52,3 @@ describe('Crypto', () => { | ||
}); | ||
it('#decryptPrivate(digest, privateKey)', () => { | ||
const plainText = 'test'; | ||
const digest = crypto.createHash('sha256').update(plainText).digest('base64'); | ||
const key = { | ||
key: config_1.TestConfig.appPrivKeyMerchant, | ||
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING | ||
}; | ||
const message = Buffer.from(digest); | ||
const encrypted = crypto.publicEncrypt(key, message).toString("base64"); | ||
const decrypted = UtilsCrypto.decryptPrivate(encrypted, config_1.TestConfig.appPrivKeyMerchant); | ||
expect(decrypted).toEqual(digest); | ||
}); | ||
it('#decryptPrivate(digest, privateKey) Error', () => { | ||
const plainText = 'test'; | ||
const digest = crypto.createHash('sha256').update(plainText).digest('base64'); | ||
const key = { | ||
key: config_1.TestConfig.appPrivKeyMerchant, | ||
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING | ||
}; | ||
const message = Buffer.from(digest); | ||
const encrypted = crypto.publicEncrypt(key, message).toString("base64"); | ||
expect(() => { UtilsCrypto.decryptPrivate(encrypted, ''); }).toThrow(new Error("an error occurred while decrypting")); | ||
}); | ||
}); | ||
//# sourceMappingURL=crypto.spec.js.map |
@@ -60,3 +60,3 @@ "use strict"; | ||
describe(`Get the Bank response once the payment is done for ${providerId}`, () => { | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking }); | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking, private_key: config_1.TestConfig.appPrivKeyOpenbanking }); | ||
const state = 'somestate'; | ||
@@ -115,3 +115,3 @@ let accessToken; | ||
it(`#initiate(providerId, dataPayload, paymentRedirectURI) for ${providerId}`, (done) => __awaiter(void 0, void 0, void 0, function* () { | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdMerchant, app_secret: config_1.TestConfig.appSecretMerchant }); | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdMerchant, app_secret: config_1.TestConfig.appSecretMerchant, private_key: config_1.TestConfig.appPrivKeyMerchant }); | ||
const token = yield client.getAccessToken(); | ||
@@ -123,3 +123,3 @@ const response = yield client.paymentInitiate(token.access_token, providerId, dataPayloadMerchant(), paymentRedirectURI); | ||
it(`#initiate(providerId, dataPayload, paymentRedirectURI, state) for ${providerId}`, (done) => __awaiter(void 0, void 0, void 0, function* () { | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdMerchant, app_secret: config_1.TestConfig.appSecretMerchant }); | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdMerchant, app_secret: config_1.TestConfig.appSecretMerchant, private_key: config_1.TestConfig.appPrivKeyMerchant }); | ||
const token = yield client.getAccessToken(); | ||
@@ -126,0 +126,0 @@ const response = yield client.paymentInitiate(token.access_token, providerId, dataPayloadMerchant(), paymentRedirectURI, 'state'); |
@@ -15,3 +15,3 @@ "use strict"; | ||
describe('Resources', () => { | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking }); | ||
const client = new fintecture_client_1.FintectureClient({ app_id: config_1.TestConfig.appIdOpenbanking, app_secret: config_1.TestConfig.appSecretOpenbanking, private_key: config_1.TestConfig.appPrivKeyOpenbanking }); | ||
it('#providers()', (done) => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -18,0 +18,0 @@ const body = yield client.getProviders(); |
@@ -1,2 +0,2 @@ | ||
import { IConfig } from './interfaces/ConfigInterface'; | ||
import { IFintectureConfig } from './interfaces/ConfigInterface'; | ||
/** | ||
@@ -14,3 +14,3 @@ * Class responsible for performing AIS calls in Fintecture API. | ||
*/ | ||
constructor(config: IConfig); | ||
constructor(config: IFintectureConfig); | ||
/** | ||
@@ -52,3 +52,3 @@ * This API is used to authenticate your customer to his Bank. | ||
*/ | ||
getAccounts(accessToken: string, customerId: string, queryParameters?: object): Promise<object>; | ||
getAccounts(accessToken: string, customerId: string, queryParameters?: object, headerParameters?: object): Promise<object>; | ||
/** | ||
@@ -63,3 +63,3 @@ * This endpoint lists all transactions on the given account | ||
*/ | ||
getTransactions(accessToken: string, customerId: string, accountId: string, queryParameters?: object): Promise<object>; | ||
getTransactions(accessToken: string, customerId: string, accountId: string, queryParameters?: object, headerParameters?: object): Promise<object>; | ||
/** | ||
@@ -74,3 +74,3 @@ * This endpoint retrieves all personal information of the clients such as name, | ||
*/ | ||
getAccountHolders(accessToken: string, customerId: string, queryParameters: object): Promise<object>; | ||
getAccountHolders(accessToken: string, customerId: string, queryParameters: object, headerParameters?: object): Promise<object>; | ||
/** | ||
@@ -85,3 +85,3 @@ * Private function that creates an instance of api | ||
private _getAxiosInstance; | ||
private _authorizeWithAccesToken; | ||
private _authorizeWithAccessToken; | ||
private _authorizeWithAppId; | ||
@@ -88,0 +88,0 @@ private _decoupledWithAccesToken; |
@@ -56,3 +56,3 @@ "use strict"; | ||
if (accessToken) { | ||
return yield this._authorizeWithAccesToken(accessToken, providerId, redirectUri, state, model, psuId, psuIpAddress); | ||
return yield this._authorizeWithAccessToken(accessToken, providerId, redirectUri, state, model, psuId, psuIpAddress); | ||
} | ||
@@ -95,8 +95,8 @@ else { | ||
*/ | ||
getAccounts(accessToken, customerId, queryParameters) { | ||
getAccounts(accessToken, customerId, queryParameters, headerParameters) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const url = `${Endpoints_1.Endpoints.AISCUSTOMER}/${customerId}/accounts`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config); | ||
const url = `${Endpoints_1.Endpoints.AISCUSTOMER}/${customerId}/accounts${queryParameters ? '?' + qs_1.default.stringify(queryParameters) : ''}`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config, null, headerParameters); | ||
return yield this.axiosInstance | ||
.get(`${url}${queryParameters ? '?' + qs_1.default.stringify(queryParameters) : ''}`, { headers }) | ||
.get(url, { headers }) | ||
.then(response => { | ||
@@ -116,8 +116,8 @@ return response.data; | ||
*/ | ||
getTransactions(accessToken, customerId, accountId, queryParameters) { | ||
getTransactions(accessToken, customerId, accountId, queryParameters, headerParameters) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const url = `${Endpoints_1.Endpoints.AISCUSTOMER}/${customerId}/accounts/${accountId}/transactions`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config); | ||
const url = `${Endpoints_1.Endpoints.AISCUSTOMER}/${customerId}/accounts/${accountId}/transactions${queryParameters ? '?' + qs_1.default.stringify(queryParameters) : ''}`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config, null, headerParameters); | ||
return yield this.axiosInstance | ||
.get(`${url}${queryParameters ? '?' + qs_1.default.stringify(queryParameters) : ''}`, { headers }) | ||
.get(url, { headers }) | ||
.then(response => { | ||
@@ -137,8 +137,8 @@ return response.data; | ||
*/ | ||
getAccountHolders(accessToken, customerId, queryParameters) { | ||
getAccountHolders(accessToken, customerId, queryParameters, headerParameters) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const url = `${Endpoints_1.Endpoints.AISCUSTOMER}/${customerId}/accountholders`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config); | ||
const url = `${Endpoints_1.Endpoints.AISCUSTOMER}/${customerId}/accountholders${queryParameters ? '?' + qs_1.default.stringify(queryParameters) : ''}`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config, null, headerParameters); | ||
return yield this.axiosInstance | ||
.get(`${Endpoints_1.Endpoints.AISCUSTOMER}/${customerId}/accountholders${queryParameters ? '?' + qs_1.default.stringify(queryParameters) : ''}`, { headers }) | ||
.get(url, { headers }) | ||
.then(response => { | ||
@@ -160,6 +160,4 @@ return response.data; | ||
} | ||
_authorizeWithAccesToken(accessToken, providerId, redirectUri, state, model, psuId, psuIpAddress) { | ||
_authorizeWithAccessToken(accessToken, providerId, redirectUri, state, model, psuId, psuIpAddress) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const url = `${Endpoints_1.Endpoints.AISPROVIDER}/${providerId}/authorize?`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config); | ||
const queryParameters = { | ||
@@ -173,6 +171,10 @@ redirect_uri: redirectUri, | ||
queryParameters['model'] = model; | ||
} | ||
const url = `${Endpoints_1.Endpoints.AISPROVIDER}/${providerId}/authorize?${qs_1.default.stringify(queryParameters)}`; | ||
const headers = apiService.getHeaders('get', url, accessToken, this.config); | ||
if (model === Constants_1.Constants.DECOUPLEDMODEL) { | ||
headers["x-psu-id"] = psuId; | ||
headers["x-psu-ip-address"] = psuIpAddress; | ||
} | ||
const response = yield this.axiosInstance.get(url + qs_1.default.stringify(queryParameters), { headers }); | ||
const response = yield this.axiosInstance.get(url, { headers }); | ||
return response.data; | ||
@@ -183,4 +185,2 @@ }); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const url = `${Endpoints_1.Endpoints.AISPROVIDER}/${providerId}/authorize?`; | ||
const headers = apiService.getHeaders('get', url, null, this.config); | ||
const queryParameters = { | ||
@@ -195,6 +195,10 @@ response_type: 'code', | ||
queryParameters['model'] = model; | ||
} | ||
const url = `${Endpoints_1.Endpoints.AISPROVIDER}/${providerId}/authorize?${qs_1.default.stringify(queryParameters)}`; | ||
const headers = apiService.getHeaders('get', url, null, this.config); | ||
if (model === Constants_1.Constants.DECOUPLEDMODEL) { | ||
headers["x-psu-id"] = psuId; | ||
headers["x-psu-ip-address"] = psuIpAddress; | ||
} | ||
const response = yield this.axiosInstance.get(url + qs_1.default.stringify(queryParameters), { headers }); | ||
const response = yield this.axiosInstance.get(url, { headers }); | ||
return response.data; | ||
@@ -201,0 +205,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
import { IConfig } from './interfaces/ConfigInterface'; | ||
import { IFintectureConfig } from './interfaces/ConfigInterface'; | ||
/** | ||
@@ -17,3 +17,3 @@ * Class responsible for performing authentication with Fintecture | ||
*/ | ||
constructor(config: IConfig); | ||
constructor(config: IFintectureConfig); | ||
/** | ||
@@ -20,0 +20,0 @@ * The accesstoken API is used to exchange the code received |
@@ -1,3 +0,3 @@ | ||
import { IConnectConfig } from './interfaces/connect/ConnectInterface'; | ||
import { IConfig } from './interfaces/ConfigInterface'; | ||
import { ISetup } from './interfaces/connect/ConnectInterface'; | ||
import { IFintectureConfig } from './interfaces/ConfigInterface'; | ||
import { PIS } from './Pis'; | ||
@@ -7,6 +7,6 @@ export declare class Connect { | ||
axios: any; | ||
config: IConfig; | ||
connectConfig: IConnectConfig; | ||
config: IFintectureConfig; | ||
connectConfig: ISetup; | ||
private signatureType; | ||
constructor(config: IConfig); | ||
constructor(config: IFintectureConfig); | ||
/** | ||
@@ -21,7 +21,4 @@ * Generates a connect URL based on the payment parameters | ||
}>; | ||
verifyUrlParameters(queryString: any): boolean; | ||
private _validateConnectConfigIntegrity; | ||
private _validatePostPaymentIntegrity; | ||
private _trowInvalidPostPaymentParameter; | ||
private _buildSignature; | ||
private _buildHeaders; | ||
private _buildPaymentPayload; | ||
@@ -28,0 +25,0 @@ private _buildSessionPayload; |
@@ -24,4 +24,4 @@ "use strict"; | ||
const Pis_1 = require("./Pis"); | ||
const apiService = __importStar(require("./services/ApiService")); | ||
class Connect { | ||
// constructor(app_id: string, app_secret: string, private_key: string, redirect_uri: string, origin_uri: string, state?: string, version?: string){ | ||
constructor(config) { | ||
@@ -44,13 +44,17 @@ this.pis = new Pis_1.PIS(config); | ||
const prepare = yield this.pis.prepare(accessToken, paymentPayload); | ||
const sessionPayload = this._buildSessionPayload(prepare.meta.session_id); | ||
const state = { | ||
const sessionPayload = this._buildSessionPayload(prepare); | ||
const headers = this._buildHeaders(accessToken, sessionPayload, this.config.private_key, this.signatureType); | ||
const config = { | ||
app_id: this.config.app_id, | ||
access_token: accessToken, | ||
signature_type: this.signatureType, | ||
signature: this._buildSignature(sessionPayload, this.config.private_key, this.signatureType), | ||
signature: headers['Signature'], | ||
redirect_uri: connectConfig.redirect_uri, | ||
origin_uri: connectConfig.origin_uri, | ||
state: connectConfig.state ? connectConfig.state : '', | ||
communication: connectConfig.communication, | ||
payload: sessionPayload | ||
payload: sessionPayload, | ||
psu_type: connectConfig.psu_type, | ||
country: connectConfig.country, | ||
date: headers['Date'], | ||
request_id: headers['X-Request-ID'] | ||
}; | ||
@@ -61,3 +65,3 @@ const url = `${this.config.env === Constants_js_1.Constants.SANDBOXENVIRONMENT | ||
const connect = { | ||
url: `${url}?state=${Buffer.from(JSON.stringify(state)).toString('base64')}`, | ||
url: `${url}?config=${Buffer.from(JSON.stringify(config)).toString('base64')}`, | ||
session_id: prepare.meta.session_id | ||
@@ -68,25 +72,2 @@ }; | ||
} | ||
verifyUrlParameters(queryString) { | ||
this.config = this._validateConfigIntegrity(this.config); | ||
this._validatePostPaymentIntegrity(queryString); | ||
const decrypted = UtilsCrypto.decryptPrivate(queryString.s, this.config.private_key); | ||
const testParams = { | ||
app_id: this.config.app_id, | ||
app_secret: this.config.app_secret, | ||
session_id: queryString.session_id, | ||
status: queryString.status, | ||
customer_id: queryString.customer_id, | ||
provider: queryString.provider, | ||
state: queryString.state, | ||
}; | ||
const testParamsArr = []; | ||
for (const key in testParams) { | ||
if (testParams.hasOwnProperty(key)) { | ||
testParamsArr.push(key + '=' + testParams[key]); | ||
} | ||
} | ||
const testParamsString = testParamsArr.join('&'); | ||
const localDigest = UtilsCrypto.hashBase64(testParamsString); | ||
return decrypted === localDigest; | ||
} | ||
_validateConnectConfigIntegrity(connectConfig) { | ||
@@ -114,31 +95,10 @@ if (!connectConfig.amount) { | ||
} | ||
connectConfig.communication = connectConfig.communication; | ||
return connectConfig; | ||
} | ||
_validatePostPaymentIntegrity(queryString) { | ||
if (typeof queryString !== 'object') { | ||
throw new Error(`invalid parameter format, the parameter must be an object instead a ${typeof queryString}`); | ||
} | ||
if (!queryString.s) { | ||
this._trowInvalidPostPaymentParameter(); | ||
} | ||
if (!queryString.status) { | ||
this._trowInvalidPostPaymentParameter(); | ||
} | ||
if (!queryString.session_id) { | ||
this._trowInvalidPostPaymentParameter(); | ||
} | ||
if (!queryString.customer_id) { | ||
this._trowInvalidPostPaymentParameter(); | ||
} | ||
if (!queryString.provider) { | ||
this._trowInvalidPostPaymentParameter(); | ||
} | ||
_buildHeaders(accessToken, payload, privateKey, algorithm) { | ||
const headers = apiService.getHeaders('post', '', accessToken, this.config, payload); | ||
const signingString = UtilsCrypto.buildSigningString(headers, Constants_js_1.Constants.CONNECTHEADERPARAMETERLIST); | ||
headers["Signature"] = UtilsCrypto.signPayload(signingString, this.config.private_key); | ||
return headers; | ||
} | ||
_trowInvalidPostPaymentParameter() { | ||
throw Error('missing query string'); | ||
} | ||
_buildSignature(payment, privateKey, algorithm) { | ||
return UtilsCrypto.signPayload(payment, privateKey, algorithm); | ||
} | ||
_buildPaymentPayload(payment) { | ||
@@ -166,7 +126,13 @@ const attributes = { | ||
} | ||
_buildSessionPayload(sessionId) { | ||
_buildSessionPayload(payment) { | ||
return { | ||
meta: { | ||
session_id: sessionId, | ||
session_id: payment.meta.session_id, | ||
}, | ||
data: { | ||
attributes: { | ||
amount: payment.data.attributes.amount, | ||
currency: payment.data.attributes.currency | ||
} | ||
} | ||
}; | ||
@@ -173,0 +139,0 @@ } |
/** | ||
* Config configuration | ||
* | ||
* @interface IConfig | ||
* @interface IFintectureConfig | ||
*/ | ||
export interface IConfig { | ||
export interface IFintectureConfig { | ||
app_id: string; | ||
@@ -8,0 +8,0 @@ app_secret: string; |
@@ -5,5 +5,5 @@ "use strict"; | ||
* | ||
* @interface IConfig | ||
* @interface IFintectureConfig | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=ConfigInterface.js.map |
@@ -5,4 +5,4 @@ import { ISessionPayload } from '../pis/PisInterface'; | ||
* | ||
* @interface ISetup | ||
* @interface IConnectConfig | ||
* @interface IState | ||
* @interface IPaymentPayload | ||
@@ -13,3 +13,3 @@ * @interface IData | ||
*/ | ||
export interface IConnectConfig { | ||
export interface ISetup { | ||
amount: number; | ||
@@ -26,3 +26,3 @@ currency: string; | ||
} | ||
export interface IState { | ||
export interface IConnectConfig { | ||
app_id: string; | ||
@@ -36,4 +36,6 @@ access_token: string; | ||
payload: ISessionPayload; | ||
version?: string; | ||
communication?: string; | ||
psu_type?: string; | ||
country?: string; | ||
date: string; | ||
request_id: string; | ||
} | ||
@@ -40,0 +42,0 @@ export interface IPaymentPayload { |
@@ -1,2 +0,2 @@ | ||
import { IConfig } from './interfaces/ConfigInterface'; | ||
import { IFintectureConfig } from './interfaces/ConfigInterface'; | ||
/** | ||
@@ -16,3 +16,3 @@ * Class responsible for performing PIS calls in Fintecture API. | ||
*/ | ||
constructor(config: IConfig); | ||
constructor(config: IFintectureConfig); | ||
/** | ||
@@ -19,0 +19,0 @@ * Prepare |
@@ -1,6 +0,6 @@ | ||
import { IConfig } from '../interfaces/ConfigInterface'; | ||
import { IFintectureConfig } from '../interfaces/ConfigInterface'; | ||
export declare const getInstance: (env: string) => import("axios").AxiosInstance; | ||
export declare const getHeaders: (method: string, url: string, accessToken: string, config: IConfig, body?: any) => { | ||
export declare const getHeaders: (method: string, url: string, accessToken: string, config: IFintectureConfig, body?: any, extraHeaders?: any) => { | ||
Accept: string; | ||
'User-Agent': string; | ||
}; |
@@ -27,3 +27,3 @@ "use strict"; | ||
}; | ||
exports.getHeaders = (method, url, accessToken, config, body) => { | ||
exports.getHeaders = (method, url, accessToken, config, body, extraHeaders) => { | ||
const headers = { | ||
@@ -42,14 +42,18 @@ Accept: 'application/json', | ||
} | ||
if (config.env === Constants_1.Constants.PRODUCTIONENVIRONMENT) { | ||
const payload = typeof body === 'string' ? body : JSON.stringify(body); | ||
const pathname = URL.parse(url).pathname; | ||
headers['Date'] = new Date().toUTCString(); | ||
if (payload) { | ||
headers['Digest'] = "SHA-256=" + Crypto.hashBase64(payload); | ||
} | ||
headers['X-Request-Id'] = Crypto.generateUUIDv4(); | ||
headers['Signature'] = Crypto.createSignatureHeader(Object.assign({ '(request-target)': method.toLowerCase() + ' ' + pathname }, headers), config); | ||
const payload = typeof body === 'string' ? body : JSON.stringify(body); | ||
const pathname = URL.parse(url).pathname; | ||
const search = URL.parse(url).search; | ||
if (body) { | ||
headers['Digest'] = "SHA-256=" + Crypto.hashBase64(payload); | ||
} | ||
headers['Date'] = new Date().toUTCString(); | ||
headers['X-Request-ID'] = Crypto.generateUUIDv4(); | ||
headers['(request-target)'] = method.toLowerCase() + ' ' + pathname + (search ? search : ''); | ||
headers['Signature'] = Crypto.createSignatureHeader(headers, config, Constants_1.Constants.SIGNEDHEADERPARAMETERLIST); | ||
delete headers['(request-target)']; | ||
if (extraHeaders) { | ||
Object.assign(headers, extraHeaders); | ||
} | ||
return headers; | ||
}; | ||
//# sourceMappingURL=ApiService.js.map |
@@ -13,2 +13,3 @@ /** | ||
static readonly SIGNEDHEADERPARAMETERLIST: string[]; | ||
static readonly CONNECTHEADERPARAMETERLIST: string[]; | ||
} |
@@ -24,3 +24,4 @@ "use strict"; | ||
Constants.DECOUPLEDMODEL = 'decoupled'; | ||
Constants.SIGNEDHEADERPARAMETERLIST = ['(request-target)', 'Date', 'Digest', 'X-Request-Id']; | ||
Constants.SIGNEDHEADERPARAMETERLIST = ['(request-target)', 'Date', 'Digest', 'X-Request-ID']; | ||
Constants.CONNECTHEADERPARAMETERLIST = ['Digest', 'X-Date', 'X-Request-ID']; | ||
//# sourceMappingURL=Constants.js.map |
@@ -1,7 +0,8 @@ | ||
import { IConfig } from '../interfaces/ConfigInterface'; | ||
import { IFintectureConfig } from '../interfaces/ConfigInterface'; | ||
export declare function generateUUID(): string; | ||
export declare function generateUUIDv4(): string; | ||
export declare function createSignatureHeader(headers: any, config: IConfig): string; | ||
export declare function createSignatureHeader(headers: any, config: IFintectureConfig, signedHeaders: any): string; | ||
export declare function buildSigningString(headers: any, signedHeaders: any): string; | ||
export declare function buildHeaderString(headers: any, signedHeaders: any): string; | ||
export declare function signPayload(payload: any, privateKey: string, algorithm?: string): string; | ||
export declare function decryptPrivate(digest: string, privateKey: string): string; | ||
export declare function hashBase64(plainText: string): string; |
@@ -12,3 +12,2 @@ "use strict"; | ||
const crypto = __importStar(require("crypto")); | ||
const Constants_1 = require("./Constants"); | ||
function generateUUID() { | ||
@@ -22,6 +21,12 @@ return uuid_1.v4().replace(/-/g, ''); | ||
exports.generateUUIDv4 = generateUUIDv4; | ||
function createSignatureHeader(headers, config) { | ||
function createSignatureHeader(headers, config, signedHeaders) { | ||
const signingString = buildSigningString(headers, signedHeaders); | ||
const headerString = buildHeaderString(headers, signedHeaders); | ||
const signature = signPayload(signingString, config.private_key); | ||
return ('keyId="' + config.app_id + '",algorithm="rsa-sha256",headers="' + headerString + '",signature="' + signature + '"'); | ||
} | ||
exports.createSignatureHeader = createSignatureHeader; | ||
function buildSigningString(headers, signedHeaders) { | ||
let signingString = ''; | ||
let headerString = ''; | ||
Constants_1.Constants.SIGNEDHEADERPARAMETERLIST.forEach(param => { | ||
signedHeaders.forEach(param => { | ||
if (headers[param]) { | ||
@@ -31,9 +36,18 @@ const p = param.toLowerCase(); | ||
signingString = signingString + p + ': ' + headers[param]; | ||
} | ||
}); | ||
return signingString; | ||
} | ||
exports.buildSigningString = buildSigningString; | ||
function buildHeaderString(headers, signedHeaders) { | ||
let headerString = ''; | ||
signedHeaders.forEach(param => { | ||
if (headers[param]) { | ||
const p = param.toLowerCase(); | ||
headerString = headerString ? headerString + ' ' + p : p; | ||
} | ||
}); | ||
const signature = signPayload(signingString, config.private_key); | ||
return ('keyId="' + config.app_id + '",algorithm="rsa-sha256",headers="' + headerString + '",signature="' + signature + '"'); | ||
return headerString; | ||
} | ||
exports.createSignatureHeader = createSignatureHeader; | ||
exports.buildHeaderString = buildHeaderString; | ||
function signPayload(payload, privateKey, algorithm) { | ||
@@ -57,17 +71,2 @@ if (typeof payload === 'object') { | ||
exports.signPayload = signPayload; | ||
function decryptPrivate(digest, privateKey) { | ||
const digestBytes = Buffer.from(digest, 'base64'); | ||
const cryptoConstants = crypto['constants']; | ||
const key = { | ||
key: privateKey, | ||
padding: cryptoConstants.RSA_PKCS1_OAEP_PADDING, | ||
}; | ||
try { | ||
return crypto.privateDecrypt(key, digestBytes).toString(); | ||
} | ||
catch (error) { | ||
throw new Error('an error occurred while decrypting'); | ||
} | ||
} | ||
exports.decryptPrivate = decryptPrivate; | ||
function hashBase64(plainText) { | ||
@@ -74,0 +73,0 @@ return crypto |
{ | ||
"name": "fintecture-client", | ||
"version": "1.0.12", | ||
"version": "1.0.13", | ||
"description": "Fintecture Open Banking API Gateway enabling secure bank connections and payments", | ||
@@ -5,0 +5,0 @@ "main": "lib/fintecture-client.js", |
@@ -28,3 +28,3 @@ # Fintecture | ||
### First Steps | ||
### Get Started | ||
@@ -203,3 +203,3 @@ Independantly of the use case, the first step is to create a developer account on the [Fintecture Console](https://console.fintecture.com/auth/register) and create an application to get your **app_id**, **app_secret** and **private_key**. | ||
// and at any time | ||
// and at any time (ex: to validate a payment on callback) | ||
let payment = await client.getPayments(tokens.access_token, connect.session_id); | ||
@@ -219,3 +219,3 @@ console.log("PAYMENT STATUS:", payment.meta.status); | ||
* origin_uri: [optional] a URL to which the customer will be redirected if he wants to exit Fintecture Connect | ||
* state: [optional] A state parameter which is sent back on callback | ||
* state: [optional] A state parameter which is sent back on callback. In the context of ecommerce, input the orderId here. | ||
@@ -222,0 +222,0 @@ ## Contributing |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
158251
86
2276