diff --git a/migrations/20211117201805-eventlog-rename-source-to-sourceJson.js b/migrations/20211117201805-eventlog-rename-source-to-sourceJson.js new file mode 100644 index 000000000..20df32136 --- /dev/null +++ b/migrations/20211117201805-eventlog-rename-source-to-sourceJson.js @@ -0,0 +1,17 @@ +'use strict'; + +const async = require('async'); + +exports.up = function(db, callback) { + async.series([ + db.runSql.bind(db, 'ALTER TABLE eventlog CHANGE source sourceJson TEXT', []), + db.runSql.bind(db, 'ALTER TABLE eventlog CHANGE data dataJson TEXT', []), + ], callback); +}; + +exports.down = function(db, callback) { + async.series([ + db.runSql.bind(db, 'ALTER TABLE eventlog CHANGE sourceJson source TEXT', []), + db.runSql.bind(db, 'ALTER TABLE eventlog CHANGE dataJson data TEXT', []), + ], callback); +}; diff --git a/migrations/schema.sql b/migrations/schema.sql index eb17b0ac4..e9153235d 100644 --- a/migrations/schema.sql +++ b/migrations/schema.sql @@ -149,8 +149,8 @@ CREATE TABLE IF NOT EXISTS backups( CREATE TABLE IF NOT EXISTS eventlog( id VARCHAR(128) NOT NULL, action VARCHAR(128) NOT NULL, - source TEXT, /* { userId, username, ip }. userId can be null for cron,sysadmin */ - data TEXT, /* free flowing json based on action */ + sourceJson TEXT, /* { userId, username, ip }. userId can be null for cron,sysadmin */ + dataJson TEXT, /* free flowing json based on action */ creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX creationTime_index (creationTime), diff --git a/src/eventlog.js b/src/eventlog.js index 726efb49d..ae18b4867 100644 --- a/src/eventlog.js +++ b/src/eventlog.js @@ -91,12 +91,14 @@ const assert = require('assert'), safe = require('safetydance'), uuid = require('uuid'); -const EVENTLOG_FIELDS = [ 'id', 'action', 'source', 'data', 'creationTime' ].join(','); +const EVENTLOG_FIELDS = [ 'id', 'action', 'sourceJson', 'dataJson', 'creationTime' ].join(','); function postProcess(record) { // usually we have sourceJson and dataJson, however since this used to be the JSON data type, we don't - record.source = safe.JSON.parse(record.source); - record.data = safe.JSON.parse(record.data); + record.source = safe.JSON.parse(record.sourceJson); + delete record.sourceJson; + record.data = safe.JSON.parse(record.dataJson); + delete record.dataJson; return record; } @@ -108,7 +110,7 @@ async function add(action, source, data) { assert.strictEqual(typeof data, 'object'); const id = uuid.v4(); - await database.query('INSERT INTO eventlog (id, action, source, data) VALUES (?, ?, ?, ?)', [ id, action, JSON.stringify(source), JSON.stringify(data) ]); + await database.query('INSERT INTO eventlog (id, action, sourceJson, dataJson) VALUES (?, ?, ?, ?)', [ id, action, JSON.stringify(source), JSON.stringify(data) ]); await notifications.onEvent(id, action, source, data); return id; } @@ -121,10 +123,10 @@ async function upsertLoginEvent(action, source, data) { // can't do a real sql upsert, for frequent eventlog entries we only have to do 2 queries once a day const queries = [{ - query: 'UPDATE eventlog SET creationTime=NOW(), data=? WHERE action = ? AND source LIKE ? AND DATE(creationTime)=CURDATE()', + query: 'UPDATE eventlog SET creationTime=NOW(), dataJson=? WHERE action = ? AND sourceJson LIKE ? AND DATE(creationTime)=CURDATE()', args: [ JSON.stringify(data), action, JSON.stringify(source) ] }, { - query: 'SELECT ' + EVENTLOG_FIELDS + ' FROM eventlog WHERE action = ? AND source LIKE ? AND DATE(creationTime)=CURDATE()', + query: 'SELECT ' + EVENTLOG_FIELDS + ' FROM eventlog WHERE action = ? AND sourceJson LIKE ? AND DATE(creationTime)=CURDATE()', args: [ action, JSON.stringify(source) ] }]; @@ -154,7 +156,7 @@ async function listPaged(actions, search, page, perPage) { let query = `SELECT ${EVENTLOG_FIELDS} FROM eventlog`; if (actions.length || search) query += ' WHERE'; - if (search) query += ' (source LIKE ' + mysql.escape('%' + search + '%') + ' OR data LIKE ' + mysql.escape('%' + search + '%') + ')'; + if (search) query += ' (sourceJson LIKE ' + mysql.escape('%' + search + '%') + ' OR dataJson LIKE ' + mysql.escape('%' + search + '%') + ')'; if (actions.length && search) query += ' AND ( '; actions.forEach(function (action, i) { diff --git a/src/test/eventlog-test.js b/src/test/eventlog-test.js index 6347f1f1c..d845adb95 100644 --- a/src/test/eventlog-test.js +++ b/src/test/eventlog-test.js @@ -102,7 +102,7 @@ describe('Eventlog', function () { let yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); - await database.query('INSERT INTO eventlog (id, action, source, data, creationTime) VALUES (?, ?, ?, ?, ?)', [ 'anotherid', 'user.login2', JSON.stringify({ ip: '1.2.3.4' }), JSON.stringify({ appId: 'thatapp' }), yesterday ]); + await database.query('INSERT INTO eventlog (id, action, sourceJson, dataJson, creationTime) VALUES (?, ?, ?, ?, ?)', [ 'anotherid', 'user.login2', JSON.stringify({ ip: '1.2.3.4' }), JSON.stringify({ appId: 'thatapp' }), yesterday ]); const result = await eventlog.upsertLoginEvent('user.login2', { ip: '1.2.3.4' }, { appId: 'thatapp' }); expect(result).to.not.equal('anotherid');