diff --git a/back/methods/osticket/closeTicket.js b/back/methods/osticket/closeTicket.js new file mode 100644 index 000000000..87d54d3b8 --- /dev/null +++ b/back/methods/osticket/closeTicket.js @@ -0,0 +1,118 @@ +const jsdom = require('jsdom'); +const mysql = require('mysql'); + +module.exports = Self => { + Self.remoteMethodCtx('closeTicket', { + description: 'Close tickets without response from the user', + accessType: 'READ', + returns: { + type: 'Object', + root: true + }, + http: { + path: `/closeTicket`, + verb: 'POST' + } + }); + + Self.closeTicket = async ctx => { + const models = Self.app.models; + const config = await models.OsTicketConfig.findOne(); + const ostUri = `${config.host}/login.php`; + + if (!config.user || !config.password || !config.userDb || !config.passwordDb) + return false; + + const con = mysql.createConnection({ + host: `${config.hostDb}`, + user: `${config.userDb}`, + password: `${config.passwordDb}`, + port: `${config.portDb}` + }); + + const sql = `SELECT ot.ticket_id, ot.number + FROM osticket.ost_ticket ot + JOIN osticket.ost_ticket_status ots ON ots.id = ot.status_id + JOIN osticket.ost_thread ot2 ON ot2.object_id = ot.ticket_id AND ot2.object_type = 'T' + JOIN ( + SELECT ote.thread_id, MAX(ote.created) created, MAX(ote.updated) updated + FROM osticket.ost_thread_entry ote + WHERE ote.staff_id != 0 AND ote.type = 'R' + GROUP BY ote.thread_id + ) sub ON sub.thread_id = ot2.id + WHERE ot.isanswered = 1 + AND ots.state = '${config.oldStatus}' + AND IF(sub.updated > sub.created, sub.updated, sub.created) < DATE_SUB(CURDATE(), INTERVAL ${config.day} DAY)`; + + let ticketsId = []; + con.connect(err => { + if (err) throw err; + con.query(sql, (err, results) => { + if (err) throw err; + for (const result of results) + ticketsId.push(result.ticket_id); + }); + }); + + await requestToken(); + + async function requestToken() { + const response = await fetch(ostUri); + + const result = response.headers.get('set-cookie'); + const [firtHeader] = result.split(' '); + const firtCookie = firtHeader.substring(0, firtHeader.length - 1); + const body = await response.text(); + const dom = new jsdom.JSDOM(body); + const token = dom.window.document.querySelector('[name="__CSRFToken__"]').value; + + await login(token, firtCookie); + } + + async function login(token, firtCookie) { + const data = { + __CSRFToken__: token, + do: 'scplogin', + userid: config.user, + passwd: config.password, + ajax: 1 + }; + const params = { + method: 'POST', + body: new URLSearchParams(data), + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'Cookie': firtCookie + } + }; + const response = await fetch(ostUri, params); + const result = response.headers.get('set-cookie'); + const [firtHeader] = result.split(' '); + const secondCookie = firtHeader.substring(0, firtHeader.length - 1); + + await close(token, secondCookie); + } + + async function close(token, secondCookie) { + for (const ticketId of ticketsId) { + const ostUri = `${config.host}/ajax.php/tickets/${ticketId}/status`; + const data = { + status_id: config.newStatusId, + comments: config.comment, + undefined: config.action + }; + const params = { + method: 'POST', + body: new URLSearchParams(data), + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'X-CSRFToken': token, + 'Cookie': secondCookie + } + }; + + return fetch(ostUri, params); + } + } + }; +}; diff --git a/back/model-config.json b/back/model-config.json index 343210383..f4adc954b 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -116,6 +116,9 @@ "OsTicket": { "dataSource": "osticket" }, + "OsTicketConfig": { + "dataSource": "vn" + }, "Edi": { "dataSource": "vn" } diff --git a/back/models/osticket-config.json b/back/models/osticket-config.json new file mode 100644 index 000000000..d42632c6a --- /dev/null +++ b/back/models/osticket-config.json @@ -0,0 +1,52 @@ +{ + "name": "OsTicketConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "osTicketConfig" + } + }, + "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, + "host": { + "type": "string" + }, + "user": { + "type": "string" + }, + "password": { + "type": "string" + }, + "oldStatus": { + "type": "string" + }, + "newStatusId": { + "type": "number" + }, + "action": { + "type": "string" + }, + "day": { + "type": "number" + }, + "comment": { + "type": "string" + }, + "hostDb": { + "type": "string" + }, + "userDb": { + "type": "string" + }, + "passwordDb": { + "type": "string" + }, + "portDb": { + "type": "number" + } + } +} \ No newline at end of file diff --git a/back/models/osticket.js b/back/models/osticket.js new file mode 100644 index 000000000..58923e08e --- /dev/null +++ b/back/models/osticket.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/osticket/closeTicket')(Self); +}; diff --git a/db/changes/10481-june/00-aclOsTicket.sql b/db/changes/10481-june/00-aclOsTicket.sql new file mode 100644 index 000000000..ae2a121f5 --- /dev/null +++ b/db/changes/10481-june/00-aclOsTicket.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('OsTicket', '*', '*', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/db/changes/10481-june/00-aclOsTicketConfig.sql b/db/changes/10481-june/00-aclOsTicketConfig.sql new file mode 100644 index 000000000..ad53ea6ae --- /dev/null +++ b/db/changes/10481-june/00-aclOsTicketConfig.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('OsTicketConfig', '*', '*', 'ALLOW', 'ROLE', 'it'); \ No newline at end of file diff --git a/db/changes/10481-june/00-osTicketConfig.sql b/db/changes/10481-june/00-osTicketConfig.sql new file mode 100644 index 000000000..ad6662715 --- /dev/null +++ b/db/changes/10481-june/00-osTicketConfig.sql @@ -0,0 +1,20 @@ +CREATE TABLE `vn`.`osTicketConfig` ( + `id` int(11) NOT NULL, + `host` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `user` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `password` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `oldStatus` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `newStatusId` int(11) DEFAULT NULL, + `action` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `day` int(11) DEFAULT NULL, + `comment` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `hostDb` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `userDb` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `passwordDb` varchar(100) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `portDb` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +INSERT INTO `vn`.`osTicketConfig`(`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `action`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`) + VALUES + (0, 'https://cau.verdnatura.es/scp', NULL, NULL, 'open', 3, 'Cerrar', 60, 'Este CAU se ha cerrado automáticamente', NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/package.json b/package.json index 13a7096d6..d33b65f93 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "i18n": "^0.8.4", "image-type": "^4.1.0", "imap": "^0.8.19", + "jsdom": "^16.7.0", "jszip": "^3.10.0", "ldapjs": "^2.2.0", "loopback": "^3.26.0",