session-desktop/libtextsecure/http-resources.js

122 lines
3.4 KiB
JavaScript
Raw Normal View History

/* global window, dcodeIO, textsecure */
// eslint-disable-next-line func-names
2019-01-16 05:44:13 +01:00
(function() {
let server;
2019-01-16 05:44:13 +01:00
const development = window.getEnvironment() !== 'production';
const pollTime = development ? 100 : 5000;
function stringToArrayBufferBase64(string) {
return dcodeIO.ByteBuffer.wrap(string, 'base64').toArrayBuffer();
}
const Response = function Response(options) {
this.verb = options.verb || options.type;
this.path = options.path || options.url;
this.body = options.body || options.data;
this.success = options.success;
this.error = options.error;
this.id = options.id;
if (this.id === undefined) {
const bits = new Uint32Array(2);
window.crypto.getRandomValues(bits);
this.id = dcodeIO.Long.fromBits(bits[0], bits[1], true);
}
if (this.body === undefined) {
this.body = null;
}
};
const IncomingHttpResponse = function IncomingHttpResponse(options) {
const request = new Response(options);
this.verb = request.verb;
this.path = request.path;
this.body = request.body;
this.respond = (status, message) => {
// Mock websocket response
window.log.info(status, message);
};
};
2019-01-16 05:44:13 +01:00
const filterIncomingMessages = async function filterIncomingMessages(
messages
) {
const incomingHashes = messages.map(m => m.hash);
2019-01-16 05:44:13 +01:00
const dupHashes = await window.Signal.Data.getSeenMessagesByHashList(
incomingHashes
);
const newMessages = messages.filter(m => !dupHashes.includes(m.hash));
const newHashes = newMessages.map(m => ({
expiresAt: m.expiration,
hash: m.hash,
}));
await window.Signal.Data.saveSeenMessageHashes(newHashes);
return newMessages;
};
window.HttpResource = function HttpResource(_server, opts = {}) {
server = _server;
let { handleRequest } = opts;
if (typeof handleRequest !== 'function') {
handleRequest = request => request.respond(404, 'Not found');
2019-01-16 05:44:13 +01:00
}
let connected = false;
const processMessages = async messages => {
const newMessages = await filterIncomingMessages(messages);
newMessages.forEach(async message => {
const { data } = message;
2019-01-21 00:46:47 +01:00
this.handleMessage(data);
});
2019-01-17 02:57:18 +01:00
};
2019-01-21 00:46:47 +01:00
this.handleMessage = message => {
2019-01-22 00:40:07 +01:00
try {
const dataPlaintext = stringToArrayBufferBase64(message);
const messageBuf = textsecure.protobuf.WebSocketMessage.decode(
dataPlaintext
2019-01-21 00:46:47 +01:00
);
2019-01-22 00:40:07 +01:00
if (
messageBuf.type === textsecure.protobuf.WebSocketMessage.Type.REQUEST
) {
handleRequest(
new IncomingHttpResponse({
verb: messageBuf.request.verb,
path: messageBuf.request.path,
body: messageBuf.request.body,
id: messageBuf.request.id,
})
);
}
} catch (error) {
const info = {
message,
error: error.message,
};
window.log.warn('HTTP-Resources Failed to handle message:', info);
2019-01-21 00:46:47 +01:00
}
};
this.startPolling = async function pollServer(callback) {
try {
await server.retrieveMessages(processMessages);
connected = true;
} catch (err) {
connected = false;
}
callback(connected);
2019-01-16 05:44:13 +01:00
setTimeout(() => {
2019-01-17 02:57:18 +01:00
pollServer(callback);
2019-01-16 05:44:13 +01:00
}, pollTime);
};
this.isConnected = function isConnected() {
return connected;
2019-01-16 05:44:13 +01:00
};
};
})();