// vim:set sw=4 ts=4 sts=4 ft=javascript expandtab: import * as lufiApi from "/js/lufi-api.browser.js" /* * Return the deciphering key stored in anchor part of the URL * Stolen from https://github.com/sebsauvage/ZeroBin/blob/master/js/zerobin.js */ function pageKey() { var key = window.location.hash.substring(1); // Get key let i; // Some stupid web 2.0 services and redirectors add data AFTER the anchor // (such as &utm_source=...). // We will strip any additional data. // First, strip everything after the equal sign (=) which signals end of base64 string. i = key.indexOf('='); let isb64 = false if (i>-1) { key = key.substring(0, i + 1); isb64 = true } // If the equal sign was not present, some parameters may remain: i = key.indexOf('&'); if (i>-1) { key = key.substring(0, i); } // Then add trailing equal sign if it's missing and was using the Sjcl algorithm if (isb64) { if (key.charAt(key.length-1)!=='=') key += '='; } return key; } // Something's wring function addAlert(msg) { $('#please-wait').remove(); var pbd = $('.file-progress'); pbd.attr('role', 'alert'); pbd.removeClass('progress'); pbd.html(`
${msg}
`); } // Spawn WebSocket function spawnWebsocket(pa) { console.log('Spawning websocket…'); var ws = new WebSocket(ws_url); ws.onopen = function () { console.log('Connection is established!'); var l = $('#loading'); l.html(i18n.loading.replace(/XX1/, (pa + 1))); if ($('#file_pwd').length === 1) { val = $('#file_pwd').val(); window.ws.send(`{"part":${pa}, "file_pwd": "${val}"}`); } else { window.ws.send(`{"part":${pa}}`); } }; ws.onclose = function () { console.log('Connection is closed'); if (!window.completed) { window.attempts++; if (window.attempts < 10) { console.log(`Connection closed. Retrying to get slice ${pa}`); window.ws = spawnWebsocket(pa); } else { alert(i18n.tooMuchAttempts); } } } ws.onmessage = function (e) { var res = e.data.split('XXMOJOXX'); var json = res.shift(); var data = JSON.parse(json); // Reset counter since we succeded to open a websocket and got a message window.attempts = 0; if (data.msg !== undefined) { addAlert(data.msg); console.log(data.msg); if ($('#file_pwd').length === 1) { $('.file-abort').addClass('hide'); } window.onbeforeunload = null; window.attempts = 10; } else { console.log(`Getting slice ${data.part + 1} of ${data.total}`); var slice = JSON.parse(res.shift()); // If file was used using Lufi API if (slice.iv) { slice.iv = new Uint8Array(Object.values(slice.iv)) } var percent = Math.round(1000 * (data.part + 1)/data.total)/10; var wClass = percent.toString().replace('.', '-'); var pb = $('#pb'); pb.removeClass(); pb.addClass('determinate'); pb.addClass(`width-${wClass}`); pb.attr('aria-valuenow', percent); $('#pbt').html(`${percent}%`); try { lufiApi.lufiCrypto.decrypt(window.key, slice).then((decrypted) => { window.a[data.part] = decrypted; if (data.part + 1 === data.total) { var blob = new Blob(a, { type: data.type }); notify(i18n.fileDownloaded, data.name); $('#please-wait').remove(); $('#loading').remove(); var pbd = $('#pbd'); pbd.attr('class', 'center-align'); // IE & Edge fix for downloading blob files, gives option to save or open the file when the link is opened. if (window.navigator && window.navigator.msSaveOrOpenBlob) { var fileName = escapeHtml(data.name); window.navigator.msSaveOrOpenBlob(blob, fileName); } else { var blobURL = URL.createObjectURL(blob); } var innerHTML = `

${i18n.download}

`; var isZip = ($('#filesize').attr('data-zipped') === 'true'); if (data.type.match(/^image\//) !== null) { innerHTML += `${escapeHtml(data.name)}`; } else if (data.type.match(/^video\//) !== null) { innerHTML += ``; } else if (data.type.match(/^audio\//) !== null) { innerHTML += ``; } else if (isZip) { innerHTML += `

${i18n.showZipContent}

`; } pbd.html(innerHTML); if (isZip) { $('#showZipContent').click(function() { JSZip.loadAsync(blob) .then(function (zip) { var innerHTML = `

${i18n.zipContent}

'; pbd.append(innerHTML); $('.download-zip-content').click(function(e) { e.preventDefault(); var t = $(this); var filename = t.attr('download'); zip.files[filename].async('blob').then(function(blob) { t.unbind('click'); t.attr('href', URL.createObjectURL(blob)); t[0].click(); }); }) $('#showZipContent').hide(); $('#showZipContent').unbind('click'); }); }); } if ($('#file_pwd').length === 1) { val = $('#file_pwd').val(); window.ws.send(`{"ended":true, "file_pwd": "${val}"}`); } else { window.ws.send('{"ended":true}'); } window.onbeforeunload = null; window.completed = true; $('#abort').remove(); } else { var l = $('#loading'); l.html(i18n.loading.replace(/XX1/, (data.part + 1))); if (ws.readyState === 3) { window.ws = spawnWebsocket(data.part + 1); } else { window.ws.onclose = function() { console.log('Connection is closed'); if (!window.completed) { console.log(`Connection closed. Retrying to get slice ${data.part + 1}`); window.ws = spawnWebsocket(data.part + 1); } } window.ws.onerror = function() { console.log(`Error. Retrying to get slice ${data.part + 1}`); window.ws = spawnWebsocket(data.part + 1); }; if ($('#file_pwd').length === 1) { val = $('#file_pwd').val(); window.ws.send(`{"part":${data.part + 1}, "file_pwd": "${val}"}`); } else { window.ws.send(`{"part":${data.part + 1}}`); } } } }).catch((e) => { console.error(e); }) } catch (err) { if (err.message === 'ccm: tag doesn\'t match') { addAlert(i18n.badkey); } else { addAlert(err.message); } window.onbeforeunload = null; } } } ws.onerror = function () { window.attempts++; if (window.attempts < 10) { console.log(`Error. Retrying to get slice ${pa}`); window.ws = spawnWebsocket(pa); } else { alert(i18n.tooMuchAttempts); } } return ws; } // When it's ready $(document).ready(function () { $('#abort').click(function () { window.ws.onclose = function () { }; window.ws.close(); $('#please-wait, #loading, #pbd, #abort').remove(); $('#filesize').parent().append(`

${i18n.aborted1}

${i18n.aborted2}

`); window.onbeforeunload = null; $('#reloadLocation').on('click', function (e) { e.preventDefault(); window.location.reload(); }) }); $('#filesize').html(filesize($('#filesize').attr('data-filesize'), { base: 10 })); window.a = new Array(); window.key = pageKey(); window.completed = false; window.attempts = 0; if (key !== '=') { var go = true; if ($('#file_pwd').length === 1) { go = false; $('#go').click(function () { $('.file-progress, .file-abort').removeClass('hide'); $('#file_pwd').parent().parent().addClass('hide'); // Set websocket window.ws = spawnWebsocket(0); // Prevent exiting page before full download window.onbeforeunload = confirmExit; }); } if (go) { // Set websocket window.ws = spawnWebsocket(0); // Prevent exiting page before full download window.onbeforeunload = confirmExit; } } else { addAlert(i18n.nokey); } });