|
|
|
@ -6,12 +6,12 @@ const nThen = require('nthen'); |
|
|
|
const Nacl = require('tweetnacl'); |
|
|
|
const Crypto = require('crypto'); |
|
|
|
|
|
|
|
|
|
|
|
let Log; |
|
|
|
const now = function () { return (new Date()).getTime(); }; |
|
|
|
|
|
|
|
const getHash = function (msg) { |
|
|
|
if (typeof(msg) !== 'string') { |
|
|
|
console.log('getHash() called on', typeof(msg), msg); |
|
|
|
Log.warn('', 'getHash() called on ' + typeof(msg) + ': ' + msg); |
|
|
|
return ''; |
|
|
|
} |
|
|
|
return msg.slice(0,64); |
|
|
|
@ -21,7 +21,7 @@ const tryParse = function (str) { |
|
|
|
try { |
|
|
|
return JSON.parse(str); |
|
|
|
} catch (err) { |
|
|
|
console.error(err); |
|
|
|
Log.error('HK_PARSE_ERROR', err); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
@ -40,10 +40,15 @@ module.exports.create = function (cfg) { |
|
|
|
const rpc = cfg.rpc; |
|
|
|
const tasks = cfg.tasks; |
|
|
|
const store = cfg.store; |
|
|
|
Log = cfg.log; |
|
|
|
|
|
|
|
Log.silly('LOADING HISTORY_KEEPER MODULE'); |
|
|
|
|
|
|
|
const historyKeeperKeys = {}; |
|
|
|
const HISTORY_KEEPER_ID = Crypto.randomBytes(8).toString('hex'); |
|
|
|
|
|
|
|
Log.verbose('History keeper ID: ' + HISTORY_KEEPER_ID); |
|
|
|
|
|
|
|
let sendMsg = function () {}; |
|
|
|
let STANDARD_CHANNEL_LENGTH, EPHEMERAL_CHANNEL_LENGTH; |
|
|
|
const setConfig = function (config) { |
|
|
|
@ -133,14 +138,13 @@ module.exports.create = function (cfg) { |
|
|
|
store.messageBin(channel.id, msgBin, waitFor(function (err) { |
|
|
|
if (err) { |
|
|
|
waitFor.abort(); |
|
|
|
return void console.log("Error writing message: " + err.message); |
|
|
|
return void Log.error("HK_STORE_MESSAGE_ERROR", err.message); |
|
|
|
} |
|
|
|
})); |
|
|
|
}).nThen((waitFor) => { |
|
|
|
getIndex(ctx, channel.id, waitFor((err, index) => { |
|
|
|
if (err) { |
|
|
|
console.log("getIndex()"); |
|
|
|
console.log(err.stack); |
|
|
|
Log.warn("HK_STORE_MESSAGE_INDEX", err.stack); |
|
|
|
// non-critical, we'll be able to get the channel index later
|
|
|
|
return; |
|
|
|
} |
|
|
|
@ -189,7 +193,7 @@ module.exports.create = function (cfg) { |
|
|
|
const validateKey = Nacl.util.decodeBase64(historyKeeperKeys[channel.id].validateKey); |
|
|
|
const validated = Nacl.sign.open(signedMsg, validateKey); |
|
|
|
if (!validated) { |
|
|
|
console.log("Signed message rejected"); // TODO logging
|
|
|
|
Log.info("HK_SIGNED_MESSAGE_REJECTED", 'Channel '+channel.id); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -309,7 +313,7 @@ module.exports.create = function (cfg) { |
|
|
|
messageBuffer.push(parsed); |
|
|
|
}, function (err) { |
|
|
|
if (err) { |
|
|
|
console.error("getOlderHistory", err); |
|
|
|
Log.error("HK_GET_OLDER_HISTORY", err); |
|
|
|
} |
|
|
|
cb(messageBuffer); |
|
|
|
}); |
|
|
|
@ -371,10 +375,13 @@ module.exports.create = function (cfg) { |
|
|
|
let parsed; |
|
|
|
let channelName; |
|
|
|
let obj = HISTORY_KEEPER_ID; |
|
|
|
|
|
|
|
Log.silly(json); |
|
|
|
|
|
|
|
try { |
|
|
|
parsed = JSON.parse(json[2]); |
|
|
|
} catch (err) { |
|
|
|
console.error("handleMessage(JSON.parse)", err); // TODO logging
|
|
|
|
Log.error("HK_PARSE_CLIENT_MESSAGE", json); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
@ -413,8 +420,8 @@ module.exports.create = function (cfg) { |
|
|
|
// if there is an error, we don't want to crash the whole server...
|
|
|
|
// just log it, and if there's a problem you'll be able to fix it
|
|
|
|
// at a later date with the provided information
|
|
|
|
console.error('Failed to write expiration to disk:', err); // TODO logging
|
|
|
|
console.error([expire, 'EXPIRE', channelName]); // TODO logging
|
|
|
|
Log.error('HK_CREATE_EXPIRE_TASK', err); |
|
|
|
Log.info('HK_INVALID_EXPIRE_TASK', JSON.stringify([expire, 'EXPIRE', channelName])); |
|
|
|
} |
|
|
|
})); |
|
|
|
}).nThen(function (waitFor) { |
|
|
|
@ -465,7 +472,7 @@ module.exports.create = function (cfg) { |
|
|
|
if (expired) { return; } |
|
|
|
|
|
|
|
if (err && err.code !== 'ENOENT') { |
|
|
|
if (err.message !== 'EINVAL') { console.error("GET_HISTORY", err); } |
|
|
|
if (err.message !== 'EINVAL') { Log.error("HK_GET_HISTORY", err); } |
|
|
|
const parsedMsg = {error:err.message, channel: channelName}; |
|
|
|
sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify(parsedMsg)]); |
|
|
|
return; |
|
|
|
@ -550,7 +557,7 @@ module.exports.create = function (cfg) { |
|
|
|
}, (err) => { |
|
|
|
let parsedMsg = ['FULL_HISTORY_END', parsed[1]]; |
|
|
|
if (err) { |
|
|
|
console.error(err.stack); |
|
|
|
Log.error('HK_GET_FULL_HISTORY', err.stack); |
|
|
|
parsedMsg = ['ERROR', parsed[1], err.message]; |
|
|
|
} |
|
|
|
sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify(parsedMsg)]); |
|
|
|
@ -582,7 +589,6 @@ module.exports.create = function (cfg) { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// TODO logging
|
|
|
|
var cciLock = false; |
|
|
|
const checkChannelIntegrity = function (ctx) { |
|
|
|
if (process.env['CRYPTPAD_DEBUG'] && !cciLock) { |
|
|
|
@ -593,10 +599,15 @@ module.exports.create = function (cfg) { |
|
|
|
if (!chan.index) { return; } |
|
|
|
nt = nt((waitFor) => { |
|
|
|
store.getChannelSize(channelName, waitFor((err, size) => { |
|
|
|
if (err) { return void console.log("Couldn't get size of channel", channelName); } |
|
|
|
if (err) { |
|
|
|
return void Log.debug("HK_CHECK_CHANNEL_INTEGRITY", |
|
|
|
"Couldn't get size of channel " + channelName); |
|
|
|
} |
|
|
|
if (size !== chan.index.size) { |
|
|
|
console.log("channel size mismatch for", channelName, |
|
|
|
"cached:", chan.index.size, "fileSize:", size); |
|
|
|
return void Log.debug("HK_CHECK_CHANNEL_SIZE", |
|
|
|
"channel size mismatch for " + channelName + |
|
|
|
" --- cached: " + chan.index.size + |
|
|
|
" --- fileSize: " + size); |
|
|
|
} |
|
|
|
})); |
|
|
|
}).nThen; |
|
|
|
|