@cafecafe/afip.ts
Version:
Afip typescript SDK
207 lines • 7.58 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AfipAuth = void 0;
const parser_1 = require("./../utils/parser");
const fs_1 = require("fs");
const path_1 = require("path");
const soap_client_facade_1 = require("../soap/soap-client-facade");
const access_ticket_1 = require("./access-ticket");
const wsdl_path_enum_1 = require("../soap/wsdl-path.enum");
const crypt_data_1 = require("../utils/crypt-data");
const enums_1 = require("../enums");
const logger_1 = require("../utils/logger");
class AfipAuth {
constructor(context) {
var _a;
this.context = context;
this.resolvedFolderPath =
(_a = context.ticketPath) !== null && _a !== void 0 ? _a : (0, path_1.resolve)(__dirname, "tickets");
}
getAuthClient() {
return __awaiter(this, void 0, void 0, function* () {
return soap_client_facade_1.SoapClientFacade.create({
wsdl: wsdl_path_enum_1.WsdlPathEnum.WSAA,
options: {
disableCache: true,
endpoint: this.context.production
? enums_1.EndpointsEnum.WSAA
: enums_1.EndpointsEnum.WSAA_TEST,
},
});
});
}
/**
* Tokent request authorization
*
* @param serviceName
* @returns
*/
getTRA(serviceName) {
const date = new Date();
return {
loginTicketRequest: {
$: { version: "1.0" },
header: [
{
uniqueId: [Math.floor(date.getTime() / 1000)],
generationTime: [new Date(date.getTime() - 600000).toISOString()],
expirationTime: [new Date(date.getTime() + 600000).toISOString()],
},
],
service: [serviceName],
},
};
}
/**
* Sign tokent request authorization
*
* @param serviceName
* @param cert
* @param key
*/
signTRA(traXml) {
const crypto = new crypt_data_1.Cryptography(this.context.cert, this.context.key);
return crypto.sign(traXml);
}
/**
* Get login cms from new request to afip
*
* @param serviceName ServiceNamesEnum
* @returns ILoginCmsReturn
*/
requestLogin(serviceName) {
return __awaiter(this, void 0, void 0, function* () {
// Create amd sign TRA
const traXml = yield parser_1.Parser.jsonToXml(this.getTRA(serviceName));
const signedTRA = this.signTRA(traXml);
// Request TR
const client = yield this.getAuthClient();
const [loginCmsResult] = yield client.loginCmsAsync({ in0: signedTRA });
const loginReturn = yield parser_1.Parser.xmlToJson(loginCmsResult.loginCmsReturn);
return new access_ticket_1.AccessTicket(loginReturn.loginticketresponse);
});
}
/**
* Creates the format of the authentication headers requested by the afip endpoints
*
* @param ticket AccessTicket
* @returns WSAuthParam
*/
getWSAuthForRequest(ticket) {
return __awaiter(this, void 0, void 0, function* () {
return {
Auth: {
Token: ticket.getToken(),
Sign: ticket.getSign(),
Cuit: this.context.cuit,
},
};
});
}
/**
* Create the file name with a standard format
*
* @param serviceName name from Afip WS
* @returns
*/
createFileName(serviceName) {
return `TA-${this.context.cuit.toString()}-${serviceName}${this.context.production ? "-production" : ""}.json`;
}
/**
* Get path to the ticket file
*
* @param serviceName ServiceNamesEnum
* @returns
*/
getTicketFilePathByService(serviceName) {
return (0, path_1.resolve)(this.resolvedFolderPath, this.createFileName(serviceName));
}
/**
* Get token authorization
*
* @param serviceName ServiceNamesEnum
* @returns AccessTicket
*/
login(serviceName) {
return __awaiter(this, void 0, void 0, function* () {
if (this.context.handleTicket)
return yield this.requestLogin(serviceName);
let accessTicket = yield this.getLocalAccessTicket(serviceName);
if (!accessTicket || accessTicket.isExpired()) {
accessTicket = yield this.requestLogin(serviceName);
yield this.saveLocalAccessTicket(accessTicket, serviceName);
}
return accessTicket;
});
}
/**
* Save the access ticket locally using file system
*
* @param ticket accessmticket header and credentials
* @param serviceName name from Afip WS
* @returns void
*/
saveLocalAccessTicket(ticket, serviceName) {
return __awaiter(this, void 0, void 0, function* () {
try {
fs_1.promises.mkdir(this.resolvedFolderPath, { recursive: true });
}
catch (error) {
logger_1.logger.error(error.message);
throw error;
}
const filePath = this.getTicketFilePathByService(serviceName);
yield fs_1.promises.writeFile(filePath, JSON.stringify(ticket), "utf8");
});
}
/**
* Get the access ticket locally using file system.
* If the file is not found, the catch take the error and return undefined.
*
* ** Check if the folder has the correct access permission. **
*
* @param serviceName name from Afip WS
* @returns access ticket or undefined if it is not there
*/
getLocalAccessTicket(serviceName) {
return __awaiter(this, void 0, void 0, function* () {
const filePath = this.getTicketFilePathByService(serviceName);
try {
yield fs_1.promises.access(filePath, fs_1.promises.constants.F_OK);
}
catch (error) {
return undefined;
}
try {
yield fs_1.promises.access(filePath, fs_1.promises.constants.R_OK);
}
catch (error) {
throw new Error(`Access denied to ticket file: ${filePath}`);
}
let fileData;
try {
fileData = yield fs_1.promises.readFile(filePath, "utf8");
}
catch (error) {
return undefined;
}
try {
return new access_ticket_1.AccessTicket(JSON.parse(fileData));
}
catch (error) {
throw new Error("Invalid access ticket format");
}
});
}
}
exports.AfipAuth = AfipAuth;
//# sourceMappingURL=afip-auth.js.map