navidev-adt-api
Version:
API de conexión al Abap Developer Tools
166 lines (165 loc) • 7.17 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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionTypes = void 0;
const httpClient_1 = __importDefault(require("../shared/httpClient/httpClient"));
const connectionConstants_1 = require("./connectionConstants");
const adtExceptionController_1 = __importDefault(require("../shared/exceptions/adtExceptionController"));
const xmlParser_1 = __importDefault(require("../shared/utilities/parser/xmlParser"));
var SessionTypes;
(function (SessionTypes) {
SessionTypes["stateful"] = "stateful";
SessionTypes["stateless"] = "stateless";
SessionTypes["keep"] = "";
})(SessionTypes || (exports.SessionTypes = SessionTypes = {}));
class ConnectionRepository {
constructor(logonData) {
this.logonData = logonData;
// Datos generales de cabecera
this.commonHeaders = {
Accept: "*/*",
"Cache-Control": "no-cache",
[`${connectionConstants_1.CSRF_TOKEN.SESSION_HEADER}`]: SessionTypes.stateful,
};
// Instancia de la clase que hará las llamadas HTTP
this.httpClient = httpClient_1.default.getInstance(this.logonData.urlBase);
this.exceptionManager = new adtExceptionController_1.default();
this.bearerToken = logonData.bearerToken;
this.cookiesAuth = logonData.cookiesAuth
? logonData.cookiesAuth
: new Map();
}
/**
* Realiza la llama a la URL con las opcionesde llamada
* @param url | URL del servicio
* @param options | Opciones de la llamada
*/
request(url, options) {
return __awaiter(this, void 0, void 0, function* () {
let httpOptions = Object.assign(Object.assign({}, options), { url, headers: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.headers), this.commonHeaders), qs: Object.assign({}, options === null || options === void 0 ? void 0 : options.qs) });
// Si hay token de autentificación se añade a la cabecera
if (this.bearerToken) {
httpOptions.headers = Object.assign(Object.assign({}, httpOptions.headers), this.getHeaderTokenAuth());
}
let response = yield this.httpClient.request(httpOptions);
// Errores de autorización u otros errores
if (response.status >= 400)
throw this.exceptionManager.fromException(response);
return response;
});
}
/**
* Login al ADT
*/
login() {
return __awaiter(this, void 0, void 0, function* () {
this.resetVariablesLogout();
// Se le pasa las opciones para generar el token de autentificación
let options = {
headers: {
[`${connectionConstants_1.CSRF_TOKEN.HEADER_VALUE}`]: connectionConstants_1.CSRF_TOKEN.FETCH,
},
auth: {
password: this.logonData.password,
username: this.logonData.username,
},
};
// Nota: No consigo pasarlo directamente y que me funcione. Porque sino me peta el ESlint me da error
// en la ejecución. La única manera en que me funcione es hacerlo de manera separada.
let params = {};
params["sap-client"] = this.logonData.client;
params["sap-language"] = this.logonData.language;
options.qs = params;
options.keepAlive = true;
options.timeout = 3600;
let response = yield this.request(connectionConstants_1.CONNECTION_URL.LOGIN, options);
// Si llega hasta aquí es que la llamada se ha efectuado correctamente, con lo cual ya se
// pueden guardar los datos de autentificación
this.bearerToken = response.headers[connectionConstants_1.CSRF_TOKEN.HEADER_VALUE];
this.extractCookiesAuth(response);
return {
bearerToken: this.bearerToken,
cookiesAuth: this.cookiesAuth,
};
});
}
/**
* Logout de la conexión
*/
logout() {
return __awaiter(this, void 0, void 0, function* () {
let options = {
headers: {
[`${connectionConstants_1.CSRF_TOKEN.SESSION_HEADER}`]: SessionTypes.stateless,
},
};
yield this.request(connectionConstants_1.CONNECTION_URL.LOGOUT, options);
this.resetVariablesLogout();
});
}
/**
* ¿Esta conectado?
*/
is_logged() {
return !!this.bearerToken;
}
/**
* Saca las cookies de autorización de la respuesta cuando se hace login
* @param response | Respuesta HTTP
*/
extractCookiesAuth(response) {
let cookiesAuth = new Map();
let cookies = response.headers["set-cookie"] || [];
cookies = xmlParser_1.default.nodeArray(cookies);
// la cookie viene con <clave>=<valor>
// En valor viene <valor>;path=<ruta>. En el primer y segundo replace se quita el "path",
// En el tercero se separa el valor del path y el valor que nos interesa, quedandonos con el valor
cookies.forEach((cookie) => {
const cookieCleaned = cookie
.replace(/path=\/,/g, "")
.replace(/path=\//g, "")
.split(";")[0];
// Se extrae el valor de la cookie
const [key] = cookie.split("=", 1);
cookiesAuth.set(key, cookieCleaned);
this.cookiesAuth = cookiesAuth;
});
}
/**
* Devuelve los datos de autorización para añadirlo al header de la llamada
* @returns Cabecera
*/
getHeaderTokenAuth() {
return {
[connectionConstants_1.CSRF_TOKEN.HEADER_VALUE]: `${this.bearerToken}`,
Cookie: this.getCookiesAuth(),
};
}
/**
* Devuelve las cookies de autorización
* @returns
*/
getCookiesAuth() {
return [...this.cookiesAuth.values()].join("; ");
}
/**
* Reset de variables internas para el login
*/
resetVariablesLogout() {
// El logout es quitar el token y las cookies
this.bearerToken = undefined;
this.cookiesAuth.clear();
}
}
exports.default = ConnectionRepository;