diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 429e2f928..2b50a088d 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -12,6 +12,7 @@ define(function () { out.type.drive = 'Drive'; out.type.whiteboard = "Tableau Blanc"; out.type.file = "Fichier"; + out.type.media = "Média"; out.button_newpad = 'Nouveau document texte'; out.button_newcode = 'Nouvelle page de code'; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 678d3c4fb..6c3ec7c4d 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -12,6 +12,7 @@ define(function () { out.type.drive = 'Drive'; out.type.whiteboard = 'Whiteboard'; out.type.file = 'File'; + out.type.media = 'Media'; out.button_newpad = 'New Rich Text pad'; out.button_newcode = 'New Code pad'; diff --git a/www/common/common-hash.js b/www/common/common-hash.js index 23f5f6a24..620acd319 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -31,8 +31,8 @@ define([ } return '/1/view/' + hexToBase64(chanKey) + '/'+Crypto.b64RemoveSlashes(keys.viewKeyStr)+'/'; }; - var getFileHashFromKey = Hash.getFileHashFromKey = function (fileKey, cryptKey, type) { - return '/2/' + hexToBase64(fileKey) + '/' + Crypto.b64RemoveSlashes(cryptKey) + '/' + Crypto.base64RemoveSlashes(type); + var getFileHashFromKeys = Hash.getFileHashFromKeys = function (fileKey, cryptKey) { + return '/2/' + hexToBase64(fileKey) + '/' + Crypto.b64RemoveSlashes(cryptKey) + '/'; }; var parsePadUrl = Hash.parsePadUrl = function (href) { @@ -122,9 +122,8 @@ define([ } } else if (version === "2") { // version 2 hashes are to be used for encrypted blobs - var fileId = secret.file = hashArray[2].replace(/-/g, '/'); - var key = secret.key = hashArray[3].replace(/-/g, '/'); - var type = secret.type = hashArray[4].replace(/-/g, '/'); + secret.channel = hashArray[2].replace(/-/g, '/'); + secret.keys = { fileKeyStr: hashArray[3].replace(/-/g, '/') }; } } } @@ -139,6 +138,9 @@ define([ if (secret.keys.viewKeyStr) { hashes.viewHash = getViewHashFromKeys(channel, secret.keys); } + if (secret.keys.fileKeyStr) { + hashes.fileHash = getFileHashFromKeys(channel, secret.keys.fileKeyStr); + } return hashes; }; @@ -187,9 +189,8 @@ Version 2 } if (hashArr[1] && hashArr[1] === '2') { parsed.version = 2; - parsed.file = hashArr[2].replace(/-/g, '/'); + parsed.channel = hashArr[2].replace(/-/g, '/'); parsed.key = hashArr[3].replace(/-/g, '/'); - parsed.type = hashArr[4].replace(/-/g, '/'); return parsed; } return; diff --git a/www/common/toolbar.js b/www/common/toolbar.js index 4162e3dbf..7ff4f2b51 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -205,6 +205,13 @@ define([ }); } } + if (hashes.fileHash) { + options.push({ + tag: 'a', + attributes: {title: Messages.viewShareTitle, 'class': 'fileShare'}, + content: ' ' + Messages.viewShare + }); + } var dropdownConfigShare = { text: $('
').append($shareIcon).append($span).html(), options: options @@ -223,7 +230,14 @@ define([ } if (hashes.viewHash) { $shareBlock.find('a.viewShare').click(function () { - var url = window.location.origin + window.location.pathname + '#' + hashes.viewHash; + var url = window.location.origin + window.location.pathname + '#' + hashes.viewHash ; + var success = Cryptpad.Clipboard.copy(url); + if (success) { Cryptpad.log(Messages.shareSuccess); } + }); + } + if (hashes.fileHash) { + $shareBlock.find('a.fileShare').click(function () { + var url = window.location.origin + window.location.pathname + '#' + hashes.fileHash ; var success = Cryptpad.Clipboard.copy(url); if (success) { Cryptpad.log(Messages.shareSuccess); } }); diff --git a/www/file/inner.html b/www/file/inner.html index bba73059e..7f315cef2 100644 --- a/www/file/inner.html +++ b/www/file/inner.html @@ -5,7 +5,6 @@ -
- + diff --git a/www/file/main.js b/www/file/main.js index b628edee9..bf7cb9e00 100644 --- a/www/file/main.js +++ b/www/file/main.js @@ -7,9 +7,11 @@ define([ '/common/visible.js', '/common/notify.js', '/bower_components/tweetnacl/nacl-fast.min.js', + '/bower_components/file-saver/FileSaver.min.js', ], function ($, Crypto, realtimeInput, Toolbar, Cryptpad, Visible, Notify) { var Messages = Cryptpad.Messages; - window.Nacl = window.nacl; + var saveAs = window.saveAs; + //window.Nacl = window.nacl; $(function () { var ifrw = $('#pad-iframe')[0].contentWindow; @@ -21,15 +23,14 @@ define([ var $bar = $iframe.find('.toolbar-container'); var secret = Cryptpad.getSecrets(); - if (secret.keys) { throw new Error("You need a hash"); } // TODO + if (!secret.keys) { throw new Error("You need a hash"); } // TODO - var cryptKey = secret.key; - var fileId = secret.file; + var cryptKey = secret.keys && secret.keys.fileKeyStr; + var fileId = secret.channel; var hexFileName = Cryptpad.base64ToHex(fileId); - var type = secret.type; - + var type = "image/png"; // Test hash: -// #/2/K6xWU-LT9BJHCQcDCT-DcQ/TBo77200c0e-FdldQFcnQx4Y/image-png +// #/2/K6xWU-LT9BJHCQcDCT-DcQ/TBo77200c0e-FdldQFcnQx4Y/ var parsed = Cryptpad.parsePadUrl(window.location.href); var defaultName = Cryptpad.getDefaultName(parsed); @@ -62,26 +63,48 @@ define([ document.title = title; }; + var blob; + var exportFile = function () { + var suggestion = document.title; + Cryptpad.prompt(Messages.exportPrompt, + Cryptpad.fixFileName(suggestion) + '.html', function (filename) { + if (!(typeof(filename) === 'string' && filename)) { return; } + //var blob = new Blob([html], {type: "text/html;charset=utf-8"}); + saveAs(blob, filename); + }); + }; + var $mt = $iframe.find('#encryptedFile'); $mt.attr('src', '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName); $mt.attr('data-crypto-key', cryptKey); $mt.attr('data-type', type); + require(['/common/media-tag.js'], function (MediaTag) { - MediaTag($mt[0]); - Cryptpad.removeLoadingScreen(); var configTb = { - displayed: ['useradmin', 'newpad'], + displayed: ['useradmin', 'share', 'newpad'], ifrw: ifrw, common: Cryptpad, title: { onRename: renameCb, defaultName: defaultName, suggestName: suggestName + }, + share: { + secret: secret, + channel: hexFileName } }; Toolbar.create($bar, null, null, null, null, configTb); + var $rightside = $bar.find('.' + Toolbar.constants.rightside); + + var $export = Cryptpad.createButton('export', true, {}, exportFile); + $rightside.append($export); updateTitle(Cryptpad.initialName || getTitle() || defaultName); + + var mt = MediaTag($mt[0]); + + Cryptpad.removeLoadingScreen(); }); }; diff --git a/www/media/assets/image.png-encrypted b/www/media/assets/image.png-encrypted new file mode 100644 index 000000000..634bb90f2 Binary files /dev/null and b/www/media/assets/image.png-encrypted differ diff --git a/www/media/index.html b/www/media/index.html new file mode 100644 index 000000000..1f8f2dcb1 --- /dev/null +++ b/www/media/index.html @@ -0,0 +1,47 @@ + + + + CryptPad + + + + + + + + + + +
+
+ +
+ +
+

+
+
+ + diff --git a/www/media/inner.html b/www/media/inner.html new file mode 100644 index 000000000..bc5b96ae0 --- /dev/null +++ b/www/media/inner.html @@ -0,0 +1,27 @@ + + + + + + + + + + +
+ + + + diff --git a/www/media/main.js b/www/media/main.js new file mode 100644 index 000000000..e176701c8 --- /dev/null +++ b/www/media/main.js @@ -0,0 +1,103 @@ +define([ + 'jquery', + '/bower_components/chainpad-crypto/crypto.js', + '/bower_components/chainpad-netflux/chainpad-netflux.js', + '/common/toolbar.js', + '/common/cryptpad-common.js', + '/common/visible.js', + '/common/notify.js', + '/bower_components/tweetnacl/nacl-fast.min.js', + '/bower_components/file-saver/FileSaver.min.js', +], function ($, Crypto, realtimeInput, Toolbar, Cryptpad, Visible, Notify) { + var Messages = Cryptpad.Messages; + var saveAs = window.saveAs; + //window.Nacl = window.nacl; + $(function () { + + var ifrw = $('#pad-iframe')[0].contentWindow; + var $iframe = $('#pad-iframe').contents(); + + Cryptpad.addLoadingScreen(); + + var andThen = function () { + var $bar = $iframe.find('.toolbar-container'); + var secret = Cryptpad.getSecrets(); + + if (!secret.keys) { throw new Error("You need a hash"); } // TODO + + var cryptKey = secret.keys && secret.keys.fileKeyStr; + var fileId = secret.channel; + var hexFileName = Cryptpad.base64ToHex(fileId); + var type = "image/png"; +// Test hash: +// #/2/K6xWU-LT9BJHCQcDCT-DcQ/TBo77200c0e-FdldQFcnQx4Y/ + + var parsed = Cryptpad.parsePadUrl(window.location.href); + var defaultName = Cryptpad.getDefaultName(parsed); + + var getTitle = function () { + var pad = Cryptpad.getRelativeHref(window.location.href); + var fo = Cryptpad.getStore().getProxy().fo; + var data = fo.getFileData(pad); + return data ? data.title : undefined; + }; + + var updateTitle = function (newTitle) { + Cryptpad.renamePad(newTitle, function (err, data) { + if (err) { + console.log("Couldn't set pad title"); + console.error(err); + return; + } + document.title = newTitle; + $bar.find('.' + Toolbar.constants.title).find('span.title').text(data); + $bar.find('.' + Toolbar.constants.title).find('input').val(data); + }); + }; + + var suggestName = function () { + return document.title || getTitle() || ''; + }; + + var renameCb = function (err, title) { + document.title = title; + }; + + var $mt = $iframe.find('#encryptedFile'); + $mt.attr('src', '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName); + $mt.attr('data-crypto-key', cryptKey); + $mt.attr('data-type', type); + + require(['/common/media-tag.js'], function (MediaTag) { + var configTb = { + displayed: ['useradmin', 'share', 'newpad'], + ifrw: ifrw, + common: Cryptpad, + title: { + onRename: renameCb, + defaultName: defaultName, + suggestName: suggestName + }, + share: { + secret: secret, + channel: hexFileName + } + }; + Toolbar.create($bar, null, null, null, null, configTb); + var $rightside = $bar.find('.' + Toolbar.constants.rightside); + + updateTitle(Cryptpad.initialName || getTitle() || defaultName); + + var mt = MediaTag($mt[0]); + + Cryptpad.removeLoadingScreen(); + }); + }; + + Cryptpad.ready(function (err, anv) { + andThen(); + Cryptpad.reportAppUsage(); + }); + + }); +});