js-gosigner-sdk
Version:
SDK for GoSigner integration
221 lines (180 loc) • 5.5 kB
JavaScript
const axios = require('axios');
const crypto = require('crypto');
const PayloadAbstract = require('../PayloadAbstract');
const File = require('../File');
const Security = require('./Security');
const SignatureSetting = require('./SignatureSetting');
const Ui = require('./Ui');
class PayloadComposer extends PayloadAbstract {
constructor() {
super();
this.skipCorsFile = false;
this.callbackUrl = null;
this.webhookUrl = null;
this.security = null;
this.ui = null;
this.extraKeys = [];
this.files = [];
this.certificates = null;
this.session = {};
}
getSkipCorsFileUrl() {
return this.skipCorsFile;
}
setSkipCorsFileUrl(skipCorsFile) {
this.skipCorsFile = skipCorsFile;
}
getCallbackUrl() {
return this.callbackUrl;
}
setCallbackUrl(callbackUrl) {
this.callbackUrl = callbackUrl;
}
getWebhookUrl() {
return this.webhookUrl;
}
setWebhookUrl(webhookUrl) {
this.webhookUrl = webhookUrl;
}
getSecurity() {
return this.security;
}
setSecurity(security) {
this.security = security;
}
getUi() {
return this.ui;
}
setUi(ui) {
this.ui = ui;
}
setExtraKeys(extraKeys) {
this.extraKeys = extraKeys;
}
getExtraKeys() {
return this.extraKeys;
}
addExtraKey(name, value) {
this.extraKeys.push({ name, value });
}
getFiles() {
return this.files;
}
setFiles(files) {
this.files = files;
}
addFile(file) {
this.files.push(file);
}
setSessionDescription(description) {
this.session = {
description,
request: true
};
}
setCertificatesFilters(filters) {
for (const filter of filters) {
for (const filterKey in filter) {
const filterValue = filter[filterKey];
switch (filterKey) {
case "validity":
case "issuer=>organizationName":
case "subjectAltName=>otherName=>2.16.76.1.3.1":
case "subjectAltName=>otherName=>2.16.76.1.3.3":
case "cn":
break;
default:
throw new Error(`${filterKey} is not allowed to certificate filter`);
}
}
}
this.certificates = { filters };
}
toArray() {
const data = {};
if (this.security) {
data.security = this.security.toArray();
}
if (this.files.length > 0) {
data.files = this.files.map(file => file.toArray ? file.toArray() : file);
if (this.skipCorsFile) {
data.files = data.files.map(file => ({
...file,
src: `${this.getBaseUrl().replace(/\/$/, "")}/resolve?download-without-cors=${encodeURIComponent(file.src)}`
}));
}
}
if (this.extraKeys.length > 0) {
data.extraKeys = this.extraKeys;
}
if (this.ui) {
data.ui = this.ui.toArray();
}
if (this.certificates) {
data.certificates = this.certificates;
}
if (Object.keys(this.session).length > 0) {
data.session = this.session;
}
if (this.callbackUrl) {
data.callbackUrl = this.callbackUrl;
}
if (this.webhookUrl) {
data.webhookUrl = this.webhookUrl;
}
return data;
}
toJson() {
return JSON.stringify(this.toArray());
}
generateToken() {
if (!this.credentials?.key) {
throw new Error("Invalid credentials key");
}
const payloadJson = this.toJson();
const payloadEncoded = Buffer.from(payloadJson).toString('base64');
const nonce = `${Date.now()}${Math.floor(Math.random() * 10000)}`;
const token = `${nonce}-${crypto.createHash('md5').update(`${nonce}${this.credentials.key}${crypto.createHash('md5').update(payloadEncoded).digest('hex')}`).digest('hex')}`;
return token;
}
async signForegroundLink(onlyToken = true) {
const baseUrl = this.getBaseUrl();
const url = `${baseUrl.replace(/\/$/, "")}/transaction-payload`;
const postData = {
partner: this.credentials.user,
token: this.generateToken(),
payload: Buffer.from(this.toJson()).toString('base64')
};
try {
const response = await axios.post(url, postData, { headers: { 'Content-Type': 'application/json' } });
const responseData = response.data;
if (onlyToken && responseData.payloadCode) {
return responseData.payloadCode; // Retorna diretamente o token
} else if (!onlyToken && responseData.redirectTo) {
return responseData.redirectTo; // Retorna o redirecionamento
} else {
throw new Error("Failed to generate token");
}
} catch (error) {
throw new Error(`API error: ${error.response ? `HTTP status code ${error.response.status}, response: ${error.response.data}` : error.message}`);
}
}
async signBackground(token) {
const [username, password] = token.split(":");
const [bearerToken, providerId] = password.split("@");
const baseUrl = this.getBaseUrl();
const url = `${baseUrl.replace(/\/$/, "")}/sign`;
try {
const response = await axios.post(url, this.toJson(), {
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${bearerToken}`
}
});
return response.data; // Retorna diretamente a resposta
} catch (error) {
throw new Error(`API error: ${error.response ? `HTTP status code ${error.response.status}, response: ${error.response.data}` : error.message}`);
}
}
}
module.exports = PayloadComposer;