0}}]),e}();e.exports=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var u={PluginExists:function(e){function t(e){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,'Plugin with same "'+e.identifier+'" identifier found.'))}return i(t,e),t}(Error),TypeNotFound:function(e){function t(){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,"Media Tag could not find the content type of an instance.}."))}return i(t,e),t}(Error),FilterExists:function(e){function t(e){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,'Filter with same "'+e.identifier+' identifier found."'))}return i(t,e),t}(Error),FetchFail:function(e){function t(e){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,'Could not fetch "'+e.url+'", received "'+e.status+": "+e.statusText+'".'))}return i(t,e),t}(Error),InvalidCryptoKey:function(e){function t(){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,"Invalid cryptographic key."))}return i(t,e),t}(Error),InvalidCryptoLib:function(e){function t(){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,"Invalid cryptographic algorithm name."))}return i(t,e),t}(Error),FailedCrypto:function(e){function t(e){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,"Failed to decrypt file"+(e&&e.message?" "+e.message:"")+"."))}return i(t,e),t}(Error)};e.exports=u},function(e,t,n){"use strict";var r=n(21),o=n(43),i=n(44),u=n(45),a=n(46),c=n(47),s=n(48),f=n(7),l=n(49),p=n(50);r.pluginStore.store(new o),r.pluginStore.store(new i),r.pluginStore.store(new u),r.pluginStore.store(new a),r.pluginStore.store(new c),r.pluginStore.store(new s),r.pluginStore.store(new f),r.pluginStore.store(new l),r.pluginStore.store(new p);var y=n(51),h=n(52);f.functionStore.store("salsa20poly1305",y),f.functionStore.store("cryptpad",h);var b=new s(" MediaTag cannot find a plugin able to renderer your content
","Download");r.processingEngine.setDefaultPlugin(b),r.CryptoFilter=f;var d=["image/png","image/jpeg","image/jpg","image/gif","audio/mp3","audio/ogg","audio/wav","audio/webm","video/mp4","video/ogg","video/webm","application/pdf","application/dash+xml","download"];r.CryptoFilter.setAllowedMediaTypes(d);var v=n(53),g=(n(14),n(0),new v);r.PdfPlugin=a,r.PdfPlugin.viewer="/pdfjs/web/viewer.html",r.processingEngine.configure(g),e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var u=n(1),a=n(5),c=n(6),s=function(e){function t(e){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,u.SANITIZER,a.EVERY))}return i(t,e),t}(c);e.exports=s},function(e,t,n){"use strict";var r=n(22),o=n(23),i=n(24),u=n(25),a=n(26),c=n(27),s=n(28),f=n(29),l=n(30),p=n(2);p.pluginStore.store(new r),p.pluginStore.store(new o),p.pluginStore.store(new i),p.pluginStore.store(new u),p.pluginStore.store(new a),p.pluginStore.store(new c),p.pluginStore.store(new s),p.pluginStore.store(new f),p.pluginStore.store(new l),e.exports=p},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var u=function(){function e(e,t){for(var n=0;n=e.STACK_LIMIT)throw console.error(this.snapshots[n]),new Error("Plugin stack size exceed");if(this.snapshots[n].length>=e.SNAPSHOT_LIMIT)throw console.error(this.snapshots[n]),new Error("Plugin snapshots size exceed");var r=0;if(this.stacks[n].forEach(function(e){e.type===a.RENDERER&&r++}),r>1)throw console.error(this.snapshots[n]),new Error("More of one renderer in the stack");if(0===this.stacks[n].length&&!this.stats[n][a.RENDERER]){if(!this.defaultPlugin)throw new Error("No default plugin assignated");this.stacks[n].unshift(this.defaultPlugin)}}},{key:"return",value:function(e){var t=e.getId(),n=this.unstack(e);if(n){try{this.stats[t]||(this.stats[t]={}),this.stats[t][n.type]?this.stats[t][n.type]+=1:this.stats[t][n.type]=1}catch(e){console.error(e,this.snapshots[t])}0===this.stacks[t].length&&n.type===a.RENDERER?this.run(e):n.type!==a.SANITIZER&&this.fill(e),this.snapshot(e),this.check(e),this.run(e)}}},{key:"process",value:function(e){var t=e.getId(),n=this.stacks[t].length,r=this.stacks[t][n-1];if(!r)throw console.log(this.stacks),new Error("Impossible to run a undefined plugin");r.process(e)}},{key:"isStacked",value:function(e,t){var n=e.getId();return!(!this.stacks[n]||!this.stacks[n].includes(t))}},{key:"setDefaultPlugin",value:function(e){this.defaultPlugin=e}}]),e}();f.STACK_LIMIT=100,f.SNAPSHOT_LIMIT=100,e.exports=f},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n0&&r(e.mediaObjects[t-1],e)}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n1?t[0]:window.location.protocol}},{key:"hostname",value:function(e){var t=e.getAttribute("src").split("://");return t.length>1?t[1].split("/")[0]:window.location.hostname}},{key:"source",value:function(e){return e.getAttribute("src")}},{key:"schemes",value:function(e){return/\w+:/.exec(e.getAttribute("src"))}},{key:"sources",value:function(e){var t=e.getAttribute("sources")||e.getAttribute("srcs");return t?JSON.parse(t):null}},{key:"actions",value:function(e){var t=e.getAttribute("actions");return t?JSON.parse(t):null}},{key:"parse",value:function(t){return{protocol:e.protocol(t),hostname:e.hostname(t),src:e.source(t),type:e.type(t),extension:e.extension(t),mime:e.mime(t),sources:e.sources(t),actions:e.actions(t)}}}]),e}();e.exports=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var u=function(){function e(e,t){for(var n=0;n1;){if("number"!=typeof e[t])throw new Error("E_UNSAFE_TYPE");if(e[t]>255)throw new Error("E_OUT_OF_BOUNDS");if(255!==e[t])return void e[t]++;if(e[t]=0,0===t)throw new Error("E_NONCE_TOO_LARGE")}}},{key:"encodePrefix",value:function(e){return[65280,255].map(function(t,n){return(e&t)>>8*(1-n)})}},{key:"decodePrefix",value:function(e){return e[0]<<8|e[1]}},{key:"joinChunks",value:function(e){return new Blob(e)}},{key:"slice",value:function(e){return Array.prototype.slice.call(e)}},{key:"getRandomKeyStr",value:function(){var e=window.nacl,t=e.randomBytes(18);return e.util.encodeBase64(t)}},{key:"getKeyFromStr",value:function(e){return window.nacl.util.decodeBase64(e)}},{key:"encrypt",value:function(){}},{key:"decrypt",value:function(t,n,r){var o=window.nacl,i=function(e){var n=new Event("decryptionProgress");n.percent=e/t.length*100,window.document.dispatchEvent(n)},u=e.createNonce(),a=0,c=t.subarray(0,2),s=e.decodePrefix(c),f={metadata:void 0},l=new Uint8Array(t.subarray(2,2+s)),p=o.secretbox.open(l,u,n);e.increment(u);try{f.metadata=JSON.parse(o.util.encodeUTF8(p))}catch(e){return r("E_METADATA_DECRYPTION")}if(!f.metadata)return r("NO_METADATA");var y=function(r){setTimeout(function(){var c=131088*a+2+s,f=c+131088;a++;var l=new Uint8Array(t.subarray(c,f)),p=o.secretbox.open(l,u,n);if(e.increment(u),!p)return void r("DECRYPTION_FAILURE");i(Math.min(f,t.length)),r(void 0,p)})},h=[];!function n(){y(function(o,i){return o?setTimeout(function(){r(o)}):i?2+s+131088*a<=t.length?(h.push(i),n()):(h.push(i),f.content=e.joinChunks(h),r(void 0,f)):void r("UNEXPECTED_ENDING")})}()}}]),e}(),l=function(){function e(){r(this,e)}return u(e,null,[{key:"getArrayBuffer",value:function(e){return fetch(e).then(function(e){if(e.ok)return e.arrayBuffer();throw new a.FetchFails}).then(function(e){return e})}},{key:"createUrl",value:function(e){return window.URL.createObjectURL(e)}},{key:"getBlobUrl",value:function(e,t){return window.URL.createObjectURL(new Blob([e],{type:t}))}},{key:"getDataUrl",value:function(e,t){return"data:"+t+";base64,"+window.nacl.util.encodeBase64(e)}}]),e}();e.exports=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n&"']/g, function (x) {
+ return ({ "<": "<", ">": ">", "&": "&", '"': """, "'": "'" })[x];
+ });
+ };
+
+
+ // Default config, can be overriden per media-tag call
+ var config = {
+ allowed: [
+ 'image/png',
+ 'image/jpeg',
+ 'image/jpg',
+ 'image/gif',
+ 'audio/mp3',
+ 'audio/ogg',
+ 'audio/wav',
+ 'audio/webm',
+ 'video/mp4',
+ 'video/ogg',
+ 'video/webm',
+ 'application/pdf',
+ //'application/dash+xml', // FIXME?
+ 'download'
+ ],
+ pdf: {},
+ download: {
+ text: "Download"
+ },
+ Plugins: {
+ image: function (metadata, url, content, cfg, cb) {
+ var img = document.createElement('img');
+ img.setAttribute('src', url);
+ img.blob = content;
+ cb(void 0, img);
+ },
+ video: function (metadata, url, content, cfg, cb) {
+ var video = document.createElement('video');
+ video.setAttribute('src', url);
+ video.setAttribute('controls', true);
+ cb(void 0, video);
+ },
+ audio: function (metadata, url, content, cfg, cb) {
+ var audio = document.createElement('audio');
+ audio.setAttribute('src', url);
+ audio.setAttribute('controls', true);
+ cb(void 0, audio);
+ },
+ pdf: function (metadata, url, content, cfg, cb) {
+ var iframe = document.createElement('iframe');
+ if (cfg.pdf.viewer) { // PDFJS
+ var viewerUrl = cfg.pdf.viewer + '?file=' + url;
+ iframe.src = viewerUrl + '#' + window.encodeURIComponent(metadata.name);
+ return void cb (void 0, iframe);
+ }
+ iframe.src = url + '#' + window.encodeURIComponent(metadata.name);
+ return void cb (void 0, iframe);
+ },
+ download: function (metadata, url, content, cfg, cb) {
+ var btn = document.createElement('button');
+ btn.setAttribute('class', 'btn btn-success');
+ btn.innerHTML = cfg.download.text + '
' +
+ (metadata.name ? '' + fixHTML(metadata.name) + '' : '');
+ btn.addEventListener('click', function () {
+ saveFile(content, url, metadata.name);
+ });
+ cb(void 0, btn);
+ }
+ }
+ };
+
+
+ // Download a blob from href
+ var download = function (src, cb) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', src, true);
+ xhr.responseType = 'arraybuffer';
+
+ xhr.onload = function () {
+ // Error?
+ if (/^4/.test('' + this.status)) { return void cb("XHR_ERROR " + this.status); }
+
+ var arrayBuffer = xhr.response;
+ if (arrayBuffer) { cb(null, new Uint8Array(arrayBuffer)); }
+ };
+
+ xhr.send(null);
+ };
+
+ // Decryption tools
+ var Decrypt = {
+ // Create a nonce
+ createNonce: function () {
+ var n = new Uint8Array(24);
+ for (var i = 0; i < 24; i++) { n[i] = 0; }
+ return n;
+ },
+
+ // Increment a nonce
+ increment: function (N) {
+ var l = N.length;
+ while (l-- > 1) {
+ /* .jshint probably suspects this is unsafe because we lack types
+ but as long as this is only used on nonces, it should be safe */
+ if (N[l] !== 255) { return void N[l]++; } // jshint ignore:line
+
+ // you don't need to worry about this running out.
+ // you'd need a REAAAALLY big file
+ if (l === 0) { throw new Error('E_NONCE_TOO_LARGE'); }
+
+ N[l] = 0;
+ }
+ },
+
+ decodePrefix: function (A) {
+ return (A[0] << 8) | A[1];
+ },
+ joinChunks: function (chunks) {
+ return new Blob(chunks);
+ },
+
+ // Convert a Uint8Array into Array.
+ slice: function (u8) {
+ return Array.prototype.slice.call(u8);
+ },
+
+ // Gets the key from the key string.
+ getKeyFromStr: function (str) {
+ return window.nacl.util.decodeBase64(str);
+ }
+ };
+
+ // Decrypts a Uint8Array with the given key.
+ var decrypt = function (u8, strKey, done, progressCb) {
+ var Nacl = window.nacl;
+
+ var progress = function (offset) {
+ progressCb((offset / u8.length) * 100);
+ };
+
+ var key = Decrypt.getKeyFromStr(strKey);
+ var nonce = Decrypt.createNonce();
+ var i = 0;
+ var prefix = u8.subarray(0, 2);
+ var metadataLength = Decrypt.decodePrefix(prefix);
+
+ var res = { metadata: undefined };
+
+ // Get metadata
+ var metaBox = new Uint8Array(u8.subarray(2, 2 + metadataLength));
+ var metaChunk = Nacl.secretbox.open(metaBox, nonce, key);
+
+ Decrypt.increment(nonce);
+
+ try { res.metadata = JSON.parse(Nacl.util.encodeUTF8(metaChunk)); }
+ catch (e) { return void done('E_METADATA_DECRYPTION'); }
+
+ if (!res.metadata) { return void done('NO_METADATA'); }
+
+ var takeChunk = function (cb) {
+ setTimeout(function () {
+ var start = i * cypherChunkLength + 2 + metadataLength;
+ var end = start + cypherChunkLength;
+ i++;
+
+ // Get the chunk
+ var box = new Uint8Array(u8.subarray(start, end));
+
+ // Decrypt the chunk
+ var plaintext = Nacl.secretbox.open(box, nonce, key);
+ Decrypt.increment(nonce);
+
+ if (!plaintext) { return void cb('DECRYPTION_FAILURE'); }
+
+ progress(Math.min(end, u8.length));
+
+ cb(void 0, plaintext);
+ });
+ };
+
+ var chunks = [];
+
+ // decrypt file contents
+ var again = function () {
+ takeChunk(function (e, plaintext) {
+ if (e) { return setTimeout(function () { done(e); }); }
+
+ if (plaintext) {
+ if (i * cypherChunkLength < u8.length) { // not done
+ chunks.push(plaintext);
+ return again();
+ }
+
+ chunks.push(plaintext);
+ res.content = Decrypt.joinChunks(chunks);
+ return void done(void 0, res);
+ }
+ done('UNEXPECTED_ENDING');
+ });
+ };
+ again();
+ };
+
+ // Get type
+ var getType = function (mediaObject, metadata, cfg) {
+ var mime = metadata.type;
+ var s = metadata.type.split('/');
+ var type = s[0];
+ var extension = s[1];
+
+ mediaObject.name = metadata.name;
+ if (mime && cfg.allowed.indexOf(mime) !== -1) {
+ mediaObject.type = type;
+ mediaObject.extension = extension;
+ mediaObject.mime = mime;
+ return type;
+ } else if (cfg.allowed.indexOf('download') !== -1) {
+ mediaObject.type = type;
+ mediaObject.extension = extension;
+ mediaObject.mime = mime;
+ return 'download';
+ } else {
+ return;
+ }
+ };
+
+ // Copy attributes
+ var copyAttributes = function (origin, dest) {
+ Object.keys(origin.attributes).forEach(function (i) {
+ if (!/^data-attr/.test(origin.attributes[i].name)) { return; }
+ var name = origin.attributes[i].name.slice(10);
+ var value = origin.attributes[i].value;
+ dest.setAttribute(name, value);
+ });
+ };
+
+ // Process
+ var process = function (mediaObject, decrypted, cfg, cb) {
+ var metadata = decrypted.metadata;
+ var blob = decrypted.content;
+
+ var mediaType = getType(mediaObject, metadata, cfg);
+
+ if (mediaType === 'application') {
+ mediaType = mediaObject.extension;
+ }
+
+ if (!mediaType || !cfg.Plugins[mediaType]) {
+ return void cb('NO_PLUGIN_FOUND');
+ }
+
+ // Get blob URL
+ var url = decrypted.url;
+ if (!url && window.URL) {
+ url = decrypted.url = window.URL.createObjectURL(new Blob([blob], {
+ type: metadata.type
+ }));
+ }
+
+ cfg.Plugins[mediaType](metadata, url, blob, cfg, function (err, el) {
+ if (err || !el) { return void cb(err || 'ERR_MEDIATAG_DISPLAY'); }
+ copyAttributes(mediaObject.tag, el);
+ mediaObject.tag.innerHTML = '';
+ mediaObject.tag.appendChild(el);
+ cb();
+ });
+ };
+
+ var addMissingConfig = function (base, target) {
+ Object.keys(target).forEach(function (k) {
+ if (!target[k]) { return; }
+ // Target is an object, fix it recursively
+ if (typeof target[k] === "object" && !Array.isArray(target[k])) {
+ // Sub-object
+ if (base[k] && (typeof base[k] !== "object" || Array.isArray(base[k]))) { return; }
+ else if (base[k]) { addMissingConfig(base[k], target[k]); }
+ else {
+ base[k] = {};
+ addMissingConfig(base[k], target[k]);
+ }
+ }
+ // Target is array or immutable, copy the value if it's missing
+ if (!base[k]) {
+ base[k] = Array.isArray(target[k]) ? JSON.parse(JSON.stringify(target[k]))
+ : target[k];
+ }
+ });
+ };
+
+ // Initialize a media-tag
+ var init = function (el, cfg) {
+ cfg = cfg || {};
+
+ addMissingConfig(cfg, config);
+
+ // Handle jQuery elements
+ if (typeof(el) === "object" && el.jQuery) { el = el[0]; }
+
+ // Abort smoothly if the element is not a media-tag
+ if (!el || el.nodeName !== "MEDIA-TAG") {
+ console.error("Not a media-tag!");
+ return {
+ on: function () { return this; }
+ };
+ }
+
+ var handlers = cfg.handlers || {
+ 'progress': [],
+ 'complete': [],
+ 'error': []
+ };
+
+ var mediaObject = el._mediaObject = {
+ handlers: handlers,
+ tag: el
+ };
+
+ var emit = function (ev, data) {
+ // Check if the event name is valid
+ if (Object.keys(handlers).indexOf(ev) === -1) {
+ return void console.error("Invalid mediatag event");
+ }
+
+ // Call the handlers
+ handlers[ev].forEach(function (h) {
+ // Make sure a bad handler won't break the media-tag script
+ try {
+ h(data);
+ } catch (err) {
+ console.error(err);
+ }
+ });
+ };
+
+ mediaObject.on = function (ev, handler) {
+ // Check if the event name is valid
+ if (Object.keys(handlers).indexOf(ev) === -1) {
+ console.error("Invalid mediatag event");
+ return mediaObject;
+ }
+ // Check if the handler is valid
+ if (typeof (handler) !== "function") {
+ console.error("Handler is not a function!");
+ return mediaObject;
+ }
+ // Add the handler
+ handlers[ev].push(handler);
+ return mediaObject;
+ };
+
+ var src = el.getAttribute('src');
+ var strKey = el.getAttribute('data-crypto-key');
+ if (/^cryptpad:/.test(strKey)) {
+ strKey = strKey.slice(9);
+ }
+ var uid = [src, strKey].join('');
+
+ // End media-tag rendering: display the tag and emit the event
+ var end = function (decrypted) {
+ process(mediaObject, decrypted, cfg, function (err) {
+ if (err) { return void emit('error', err); }
+ emit('complete', decrypted);
+ });
+ };
+
+ // If we have the blob in our cache, don't download & decrypt it again, just display
+ if (cache[uid]) {
+ end(cache[uid]);
+ return mediaObject;
+ }
+
+ // Download the encrypted blob
+ download(src, function (err, u8Encrypted) {
+ if (err) {
+ return void emit('error', err);
+ }
+ // Decrypt the blob
+ decrypt(u8Encrypted, strKey, function (errDecryption, u8Decrypted) {
+ if (errDecryption) {
+ return void emit('error', errDecryption);
+ }
+ // Cache and display the decrypted blob
+ cache[uid] = u8Decrypted;
+ end(u8Decrypted);
+ }, function (progress) {
+ emit('progress', {
+ progress: progress
+ });
+ });
+ });
+
+ return mediaObject;
+ };
+
+ // Add the cache as a property of MediaTag
+ cache = init.__Cryptpad_Cache = {};
+
+ init.setDefaultConfig = function (key, value) {
+ config[key] = value;
+ };
+
+ return init;
+}));
diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js
index 8b2270797..d43375ef2 100644
--- a/www/common/outer/userObject.js
+++ b/www/common/outer/userObject.js
@@ -111,7 +111,7 @@ define([
// RPC may not be responding
// Send a report that can be handled manually
console.error(obj.error);
- Feedback.send('ERROR_DELETING_OWNED_PAD=' + channelId, true);
+ Feedback.send('ERROR_DELETING_OWNED_PAD=' + channelId + '|' + obj.error, true);
}
});
}
diff --git a/www/common/sframe-common-title.js b/www/common/sframe-common-title.js
index 317944993..0a838ef34 100644
--- a/www/common/sframe-common-title.js
+++ b/www/common/sframe-common-title.js
@@ -42,6 +42,9 @@ define([
exp.updateTitle = function (newTitle, cb) {
cb = cb || $.noop;
if (newTitle === exp.title) { return void cb(); }
+ if (newTitle === exp.defaultTitle) {
+ newTitle = "";
+ }
metadataMgr.updateTitle(newTitle);
titleUpdated = cb;
};
@@ -51,7 +54,9 @@ define([
if ($title) {
$title.find('span.cp-toolbar-title-value').text(md.title || md.defaultTitle);
$title.find('input').val(md.title || md.defaultTitle);
+ $title.find('input').prop('placeholder', md.defaultTitle);
}
+ exp.defaultTitle = md.defaultTitle;
exp.title = md.title;
});
metadataMgr.onTitleChange(function (title) {
diff --git a/www/file/inner.js b/www/file/inner.js
index 78d162f5e..1e2a4f3e1 100644
--- a/www/file/inner.js
+++ b/www/file/inner.js
@@ -37,6 +37,9 @@ define([
var Nacl = window.nacl;
var APP = window.APP = {};
+ MediaTag.setDefaultConfig('download', {
+ text: Messages.download_mt_button
+ });
var andThen = function (common) {
var $appContainer = $('#cp-app-file-content');
@@ -130,32 +133,17 @@ define([
$mt.attr('data-crypto-key', 'cryptpad:'+cryptKey);
var rightsideDisplayed = false;
- $(window.document).on('decryption', function (e) {
- /* FIXME
- we're listening for decryption events and assuming that only
- the main media-tag exists. In practice there is also your avatar
- and there could be other things in the future, so we should
- figure out a generic way target media-tag decryption events.
- */
- var decrypted = e.originalEvent;
- if (decrypted.callback) {
- decrypted.callback();
- }
+ MediaTag($mt[0]).on('complete', function (decrypted) {
$dlview.show();
$dlform.hide();
var $dlButton = $dlview.find('media-tag button');
if (ev) { $dlButton.click(); }
- $dlButton.addClass('btn btn-success');
- var text = Messages.download_mt_button + '
';
- text += '' + Util.fixHTML(title) + '
';
- text += '' + Messages._getKey('formattedMB', [sizeMb]) + '';
- $dlButton.html(text);
if (!rightsideDisplayed) {
toolbar.$rightside
.append(common.createButton('export', true, {}, function () {
- saveAs(decrypted.blob, decrypted.metadata.name);
+ saveAs(decrypted.content, decrypted.metadata.name);
}));
rightsideDisplayed = true;
}
@@ -178,42 +166,12 @@ define([
} else {
cb();
}
- })
- .on('decryptionError', function (e) {
- var error = e.originalEvent;
- //UI.alert(error.message);
- cb(error.message);
- })
- .on('decryptionProgress', function (e) {
- var progress = e.originalEvent;
- var p = progress.percent +'%';
+ }).on('progress', function (data) {
+ var p = data.progress +'%';
$progress.width(p);
+ }).on('error', function (err) {
+ console.error(err);
});
-
- /**
- * Allowed mime types that have to be set for a rendering after a decryption.
- *
- * @type {Array}
- */
- var allowedMediaTypes = [
- 'image/png',
- 'image/jpeg',
- 'image/jpg',
- 'image/gif',
- 'audio/mp3',
- 'audio/ogg',
- 'audio/wav',
- 'audio/webm',
- 'video/mp4',
- 'video/ogg',
- 'video/webm',
- 'application/pdf',
- 'application/dash+xml',
- 'download'
- ];
- MediaTag.CryptoFilter.setAllowedMediaTypes(allowedMediaTypes);
-
- MediaTag($mt[0]);
};
var todoBigFile = function (sizeMb) {
diff --git a/www/filepicker/app-filepicker.less b/www/filepicker/app-filepicker.less
index 952a4d857..5a80661cf 100644
--- a/www/filepicker/app-filepicker.less
+++ b/www/filepicker/app-filepicker.less
@@ -4,11 +4,15 @@
@import (once) '../../customize/src/less2/include/fileupload.less';
@import (once) '../../customize/src/less2/include/alertify.less';
@import (once) '../../customize/src/less2/include/tippy.less';
+@import (once) '../../customize/src/less2/include/checkmark.less';
+@import (once) '../../customize/src/less2/include/password-input.less';
.iconColors_main();
.fileupload_main();
.alertify_main();
.tippy_main();
+.checkmark_main(20px);
+.password_main();
#cp-filepicker-dialog {
display: none;
diff --git a/www/mediatag/media-tag.js b/www/mediatag/media-tag.js
index f240e0941..9ae19d3a8 100644
--- a/www/mediatag/media-tag.js
+++ b/www/mediatag/media-tag.js
@@ -4,7 +4,6 @@
else { this[name] = definition(); }
}('MediaTag', function() {
var cache;
- var PARANOIA = true;
var cypherChunkLength = 131088;
// Save a blob on the file system
@@ -23,6 +22,14 @@
}
};
+ var fixHTML = function (str) {
+ if (!str) { return ''; }
+ return str.replace(/[<>&"']/g, function (x) {
+ return ({ "<": "<", ">": ">", "&": "&", '"': """, "'": "'" })[x];
+ });
+ };
+
+
// Default config, can be overriden per media-tag call
var config = {
allowed: [
@@ -49,6 +56,7 @@
image: function (metadata, url, content, cfg, cb) {
var img = document.createElement('img');
img.setAttribute('src', url);
+ img.blob = content;
cb(void 0, img);
},
video: function (metadata, url, content, cfg, cb) {
@@ -75,7 +83,8 @@
},
download: function (metadata, url, content, cfg, cb) {
var btn = document.createElement('button');
- btn.innerHTML = cfg.download.text;
+ btn.innerHTML = cfg.download.text + '
' +
+ metadata.name ? '' + fixHTML(metadata.name) + '' : '';
btn.addEventListener('click', function () {
saveFile(content, url, metadata.name);
});
@@ -106,38 +115,24 @@
var Decrypt = {
// Create a nonce
createNonce: function () {
- if (!Array.prototype.fill) {
- // IE support
- var arr = [];
- for (var i = 0; i < 24; i++) { arr[i] = 0; }
- return new Uint8Array(arr);
- }
- return new Uint8Array(new Array(24).fill(0));
+ var n = new Uint8Array(24);
+ for (var i = 0; i < 24; i++) { n[i] = 0; }
+ return n;
},
// Increment a nonce
- // FIXME: remove throw?
increment: function (N) {
var l = N.length;
while (l-- > 1) {
- if (PARANOIA) {
- if (typeof(N[l]) !== 'number') {
- throw new Error('E_UNSAFE_TYPE');
- }
- if (N[l] > 255) {
- throw new Error('E_OUT_OF_BOUNDS');
- }
- }
/* .jshint probably suspects this is unsafe because we lack types
but as long as this is only used on nonces, it should be safe */
if (N[l] !== 255) { return void N[l]++; } // jshint ignore:line
- N[l] = 0;
// you don't need to worry about this running out.
// you'd need a REAAAALLY big file
- if (l === 0) {
- throw new Error('E_NONCE_TOO_LARGE');
- }
+ if (l === 0) { throw new Error('E_NONCE_TOO_LARGE'); }
+
+ N[l] = 0;
}
},
@@ -153,13 +148,6 @@
return Array.prototype.slice.call(u8);
},
- // Gets the random key string.
- getRandomKeyStr: function () {
- var Nacl = window.nacl;
- var rdm = Nacl.randomBytes(18);
- return Nacl.util.encodeBase64(rdm);
- },
-
// Gets the key from the key string.
getKeyFromStr: function (str) {
return window.nacl.util.decodeBase64(str);
@@ -287,7 +275,7 @@
// Get blob URL
var url = decrypted.url;
- if (!url) {
+ if (!url && window.URL) {
url = decrypted.url = window.URL.createObjectURL(new Blob([blob], {
type: metadata.type
}));
diff --git a/www/pad/inner.js b/www/pad/inner.js
index b8199bc61..865be9ef8 100644
--- a/www/pad/inner.js
+++ b/www/pad/inner.js
@@ -601,8 +601,8 @@ define([
var $clone = $(inner).clone();
nThen(function (waitFor) {
$(inner).find('media-tag').each(function (i, el) {
- if (!$(el).data('blob')) { return; }
- Util.blobToImage($(el).data('blob'), waitFor(function (imgSrc) {
+ if (!$(el).data('blob') || !el.blob) { return; }
+ Util.blobToImage(el.blob || $(el).data('blob'), waitFor(function (imgSrc) {
$clone.find('media-tag[src="' + $(el).attr('src') + '"] img')
.attr('src', imgSrc);
$clone.find('media-tag').parent()
diff --git a/www/profile/inner.js b/www/profile/inner.js
index 40642507a..76c279ce0 100644
--- a/www/profile/inner.js
+++ b/www/profile/inner.js
@@ -43,16 +43,6 @@ define([
_onRefresh: []
};
- // Decryption event for avatar mediatag (TODO not needed anymore?)
- $(window.document).on('decryption', function (e) {
- var decrypted = e.originalEvent;
- if (decrypted.callback) { decrypted.callback(); }
- })
- .on('decryptionError', function (e) {
- var error = e.originalEvent;
- UI.alert(error.message);
- });
-
$(window).click(function () {
$('.cp-dropdown-content').hide();
});