UNPKG

@retracedhq/retraced

Version:

The official NodeJS client for interacting with the Retraced audit logging API.

230 lines (229 loc) 7.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.stringifyStructuredQuery = exports.graphQLQuery = exports.formatRawEventNode = exports.EventsConnection = void 0; const _ = require("lodash"); const axios_1 = require("axios"); class EventsConnection { constructor(url, authorization, query, mask, pageSize) { this.url = url; this.authorization = authorization; this.query = query; this.mask = mask; this.pageSize = pageSize; this.cursors = []; this.totalCount = 0; } totalPages() { return Math.ceil(this.totalCount / this.pageSize); } hasPreviousPage() { return this.currentPageNumber > 1; } hasNextPage() { return this.currentPageNumber < this.totalPages(); } async init() { this.cursors.push(""); await this.call(); } async nextPage() { await this.call(); } async call() { const cursor = _.last(this.cursors); const body = { query: (0, exports.graphQLQuery)(this.mask), variables: { query: (0, exports.stringifyStructuredQuery)(this.query), last: this.pageSize, before: cursor, }, }; let searchData; try { const rsp = await axios_1.default.post(this.url, body, { headers: { Accept: "application/json", Authorization: this.authorization, }, }); searchData = rsp.data; } catch (err) { const status = err.response ? err.response.status : 500; const statusText = err.response ? err.response.statusText : "Unknown"; throw new Error(`Unexpected HTTP response: ${status} ${statusText}`); } const { data } = searchData; this.totalCount = data.search.totalCount; this.currentResults = data.search.edges.map((edge) => { return (0, exports.formatRawEventNode)(edge.node); }); this.currentPageNumber = this.cursors.length; if (data.search.pageInfo.hasPreviousPage) { this.cursors.push(_.last(data.search.edges).cursor); } } } exports.EventsConnection = EventsConnection; const fieldsMap = (fieldsList) => { const fields = {}; return fieldsList.reduce((accm, field) => { accm[field.key] = field.value; return accm; }, fields); }; const formatRawEventNode = (node) => { const conversions = {}; if (node.received) { conversions.received = new Date(node.received); } if (node.created) { conversions.created = new Date(node.created); } if (node.canonical_time) { conversions.canonical_time = new Date(node.canonical_time); } if (node.fields) { conversions.fields = fieldsMap(node.fields); } if (node.actor && node.actor.fields) { conversions.actor = _.extend(node.actor, { fields: fieldsMap(node.actor.fields), }); } if (node.target && node.target.fields) { conversions.target = _.extend(node.target, { fields: fieldsMap(node.target.fields), }); } return _.extend(node, conversions); }; exports.formatRawEventNode = formatRawEventNode; const graphQLQuery = (mask) => { let group = ""; if (mask.group && (mask.group.id || mask.group.name)) { group = `group { ${mask.group.id ? "id" : ""} ${mask.group.name ? "name" : ""} }`; } let actor = ""; if (mask.actor && (mask.actor.id || mask.actor.name || mask.actor.href || mask.actor.fields)) { actor = `actor { ${mask.actor.id ? "id" : ""} ${mask.actor.name ? "name" : ""} ${mask.actor.href ? "href" : ""} ${mask.actor.fields ? `fields { key value }` : ""} }`; } let target = ""; if (mask.target && (mask.target.id || mask.target.name || mask.target.href || mask.target.type || mask.target.fields)) { target = `target { ${mask.target.id ? "id" : ""} ${mask.target.name ? "name" : ""} ${mask.target.href ? "href" : ""} ${mask.target.type ? "type" : ""} ${mask.target.fields ? `fields { key value }` : ""} }`; } let display = ""; if (mask.display && mask.display.markdown) { display = `display { markdown }`; } const q = `query Search($query: String!, $last: Int, $before: String) { search(query: $query, last: $last, before: $before) { totalCount, pageInfo { hasPreviousPage } edges { cursor node { ${mask.id ? "id" : ""} ${mask.action ? "action" : ""} ${mask.description ? "description" : ""} ${group} ${actor} ${target} ${mask.crud ? "crud" : ""} ${display} ${mask.received ? "received" : ""} ${mask.created ? "created" : ""} ${mask.canonical_time ? "canonical_time" : ""} ${mask.is_failure ? "is_failure" : ""} ${mask.is_anonymous ? "is_anonymous" : ""} ${mask.source_ip ? "country" : ""} ${mask.loc_subdiv1 ? "loc_subdiv1" : ""} ${mask.loc_subdiv2 ? "loc_subdiv2" : ""} ${mask.component ? "component" : ""} ${mask.version ? "version" : ""} ${mask.fields ? `fields { key value }` : ""} ${mask.external_id ? "external_id" : ""} ${mask.metadata ? `metadata { key value }` : ""} } } } }`; return q .split(/\n/) .filter((line) => line.trim()) .join("\n"); }; exports.graphQLQuery = graphQLQuery; const stringifyStructuredQuery = (queryObj) => { const params = []; if (queryObj.action) { params.push(`action:"${queryObj.action}"`); } if (queryObj.crud) { params.push(`crud:${queryObj.crud}`); } if (queryObj.received_start || queryObj.received_end) { const start = queryObj.received_start ? queryObj.received_start.toISOString() : ""; const end = queryObj.received_end ? queryObj.received_end.toISOString() : ""; params.push(`received:${start},${end}`); } if (queryObj.created_start || queryObj.created_end) { const start = queryObj.created_start ? queryObj.created_start.toISOString() : ""; const end = queryObj.created_end ? queryObj.created_end.toISOString() : ""; params.push(`created:${start},${end}`); } if (queryObj.actor_name) { params.push(`actor.name:"${queryObj.actor_name}"`); } if (queryObj.actor_id) { params.push(`actor.id:${queryObj.actor_id}`); } if (queryObj.description) { params.push(`description:"${queryObj.description}"`); } if (queryObj.location) { params.push(`location:"${queryObj.location}"`); } return params.join(" "); }; exports.stringifyStructuredQuery = stringifyStructuredQuery;