UNPKG

@cafecafe/afip.ts

Version:
207 lines 7.58 kB
"use strict"; 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