mirror of https://github.com/xwiki-labs/cryptpad
Integrate filepicker secure iframe in the code2 app
This commit is contained in:
parent
89b7b644f3
commit
f12f4bb925
|
@ -24,6 +24,15 @@
|
|||
padding:0;
|
||||
overflow:hidden;
|
||||
}
|
||||
#sbox-filePicker-iframe {
|
||||
position: fixed;
|
||||
top:0; left:0;
|
||||
bottom:0; right:0;
|
||||
width:100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -228,9 +228,9 @@ define([
|
|||
APP.previewTo = window.setTimeout(function () {
|
||||
$codeMirror.removeClass('transition');
|
||||
}, 500);
|
||||
/*if (mediaTagModes.indexOf(mode) !== -1) {
|
||||
if (mediaTagModes.indexOf(mode) !== -1) {
|
||||
APP.$mediaTagButton.show();
|
||||
} else { APP.$mediaTagButton.hide(); }*/// TODO
|
||||
} else { APP.$mediaTagButton.hide(); }
|
||||
|
||||
if (mode === "markdown") {
|
||||
APP.$previewButton.show();
|
||||
|
@ -360,26 +360,20 @@ define([
|
|||
else {
|
||||
CodeMirror.configureTheme();
|
||||
}
|
||||
// TODO
|
||||
return;
|
||||
|
||||
var fileDialogCfg = {
|
||||
$body: $iframe.find('body'),
|
||||
onSelect: function (href) {
|
||||
var parsed = Cryptpad.parsePadUrl(href);
|
||||
var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel);
|
||||
var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName;
|
||||
var mt = '<media-tag src="' + src + '" data-crypto-key="cryptpad:' + parsed.hashData.key + '"></media-tag>';
|
||||
onSelect: function (data) {
|
||||
var mt = '<media-tag src="' + data.src + '" data-crypto-key="cryptpad:' + data.key + '"></media-tag>';
|
||||
editor.replaceSelection(mt);
|
||||
},
|
||||
data: APP
|
||||
}
|
||||
};
|
||||
common.initFilePicker(common, fileDialogCfg);
|
||||
APP.$mediaTagButton = $('<button>', {
|
||||
title: Messages.filePickerButton,
|
||||
'class': 'rightside-button fa fa-picture-o',
|
||||
style: 'font-size: 17px'
|
||||
}).click(function () {
|
||||
Cryptpad.createFileDialog(fileDialogCfg);
|
||||
common.openFilePicker(common);
|
||||
}).appendTo($rightside);
|
||||
|
||||
};
|
||||
|
|
|
@ -751,7 +751,6 @@ define([
|
|||
list[id] = data;
|
||||
}
|
||||
});
|
||||
console.log(list);
|
||||
cb (null, list);
|
||||
};
|
||||
|
||||
|
@ -1464,16 +1463,24 @@ define([
|
|||
'id': cfg.id
|
||||
});
|
||||
}
|
||||
var hide = function () {
|
||||
if (cfg.onClose) { return void cfg.onClose(); }
|
||||
$blockContainer.hide();
|
||||
};
|
||||
$blockContainer.html('').appendTo($body);
|
||||
var $block = $('<div>', {'class': 'cp-modal'}).appendTo($blockContainer);
|
||||
$('<span>', {
|
||||
'class': 'cp-modal-close fa fa-times',
|
||||
'title': Messages.filePicker_close
|
||||
}).click(function () {
|
||||
$blockContainer.hide();
|
||||
}).appendTo($block);
|
||||
}).click(hide).appendTo($block);
|
||||
$body.click(hide);
|
||||
$block.click(function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
$body.keydown(function (e) {
|
||||
if (e.which === 27) { $blockContainer.hide(); }
|
||||
if (e.which === 27) {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
return $blockContainer;
|
||||
};
|
||||
|
|
|
@ -109,8 +109,9 @@ define([
|
|||
window.addEventListener('message', function (msg) {
|
||||
var data = JSON.parse(msg.data);
|
||||
if (ow !== msg.source) {
|
||||
console.log("DROP Message from unexpected source");
|
||||
console.log(msg);
|
||||
return;
|
||||
//console.log("DROP Message from unexpected source");
|
||||
//console.log(msg);
|
||||
} else if (!otherWindow) {
|
||||
otherWindow = ow;
|
||||
ow.postMessage(JSON.stringify({ txid: data.txid }), '*');
|
||||
|
|
|
@ -261,18 +261,40 @@ define([
|
|||
return $userAdmin;
|
||||
};
|
||||
|
||||
// createFileDialog can only be used in filepicker due to access rights restrictions
|
||||
UI.createFileDialog = function (cfg) {
|
||||
var common = cfg.common;
|
||||
var sframeChan = common.getSframeChannel();
|
||||
var updateContainer;
|
||||
var hideFileDialog = function () {
|
||||
sframeChan.event('EV_FILE_PICKER_CLOSE');
|
||||
};
|
||||
// Create modal
|
||||
var $blockContainer = Cryptpad.createModal({
|
||||
id: 'fileDialog',
|
||||
$body: cfg.$body
|
||||
});
|
||||
$body: cfg.$body,
|
||||
onClose: hideFileDialog
|
||||
}).show();
|
||||
// Set the fixed content
|
||||
var $block = $blockContainer.find('.cp-modal');
|
||||
var $description = $('<p>').text(Messages.filePicker_description);
|
||||
$block.append($description);
|
||||
var $filter = $('<p>', {'class': 'cp-modal-form'}).appendTo($block);
|
||||
var to;
|
||||
$('<input>', {
|
||||
type: 'text',
|
||||
'class': 'filter',
|
||||
'placeholder': Messages.filePicker_filter
|
||||
}).appendTo($filter).on('keypress', function () {
|
||||
if (to) { window.clearTimeout(to); }
|
||||
to = window.setTimeout(updateContainer, 300);
|
||||
});
|
||||
$filter.append(common.createButton('upload', false, cfg.data, function () {
|
||||
hideFileDialog();
|
||||
}));
|
||||
var $container = $('<span>', {'class': 'fileContainer'}).appendTo($block);
|
||||
var updateContainer = function () {
|
||||
// Update the files list when needed
|
||||
updateContainer = function () {
|
||||
$container.html('');
|
||||
var filter = $filter.find('.filter').val().trim();
|
||||
var todo = function (err, list) {
|
||||
|
@ -291,28 +313,27 @@ define([
|
|||
$span.append(name);
|
||||
$span.click(function () {
|
||||
if (typeof cfg.onSelect === "function") { cfg.onSelect(data.href); }
|
||||
$blockContainer.hide();
|
||||
hideFileDialog();
|
||||
});
|
||||
});
|
||||
};
|
||||
common.getFilesList(todo);
|
||||
};
|
||||
var to;
|
||||
$('<input>', {
|
||||
type: 'text',
|
||||
'class': 'filter',
|
||||
'placeholder': Messages.filePicker_filter
|
||||
}).appendTo($filter).on('keypress', function () {
|
||||
if (to) { window.clearTimeout(to); }
|
||||
to = window.setTimeout(updateContainer, 300);
|
||||
});
|
||||
//$filter.append(' '+Messages.or+' ');
|
||||
/*var data = {FM: cfg.data.FM};
|
||||
$filter.append(common.createButton('upload', false, data, function () {
|
||||
$blockContainer.hide();
|
||||
}));*/
|
||||
updateContainer();
|
||||
$blockContainer.show();
|
||||
sframeChan.on('EV_FILE_PICKER_REFRESH', updateContainer);
|
||||
};
|
||||
|
||||
|
||||
UI.initFilePicker = function (common, cfg) {
|
||||
var onSelect = cfg.onSelect || $.noop;
|
||||
var sframeChan = common.getSframeChannel();
|
||||
sframeChan.on("EV_FILE_PICKED", function (data) {
|
||||
onSelect(data);
|
||||
});
|
||||
};
|
||||
UI.openFilePicker = function (common) {
|
||||
var sframeChan = common.getSframeChannel();
|
||||
sframeChan.event("EV_FILE_PICKER_OPEN");
|
||||
};
|
||||
|
||||
return UI;
|
||||
|
|
|
@ -14,6 +14,7 @@ define([
|
|||
var Crypto;
|
||||
var Cryptget;
|
||||
var sframeChan;
|
||||
var FilePicker;
|
||||
|
||||
nThen(function (waitFor) {
|
||||
// Load #2, the loading screen is up so grab whatever you need...
|
||||
|
@ -23,11 +24,14 @@ define([
|
|||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/common/cryptget.js',
|
||||
'/common/sframe-channel.js',
|
||||
], waitFor(function (_CpNfOuter, _Cryptpad, _Crypto, _Cryptget, SFrameChannel) {
|
||||
'/filepicker/main.js',
|
||||
], waitFor(function (_CpNfOuter, _Cryptpad, _Crypto, _Cryptget, SFrameChannel,
|
||||
_FilePicker) {
|
||||
CpNfOuter = _CpNfOuter;
|
||||
Cryptpad = _Cryptpad;
|
||||
Crypto = _Crypto;
|
||||
Cryptget = _Cryptget;
|
||||
FilePicker = _FilePicker;
|
||||
SFrameChannel.create($('#sbox-iframe')[0].contentWindow, waitFor(function (sfc) {
|
||||
sframeChan = sfc;
|
||||
}));
|
||||
|
@ -215,7 +219,7 @@ define([
|
|||
});
|
||||
|
||||
|
||||
sframeChan.on('Q_UPLOAD_FILE', function (data, cb) {
|
||||
var onFileUpload = function (sframeChan, data, cb) {
|
||||
var sendEvent = function (data) {
|
||||
sframeChan.event("EV_FILE_UPLOAD_STATE", data);
|
||||
};
|
||||
|
@ -245,6 +249,31 @@ define([
|
|||
data.blob = Crypto.Nacl.util.decodeBase64(data.blob);
|
||||
Cryptpad.uploadFileSecure(data, data.noStore, Cryptpad, updateProgress, onComplete, onError, onPending);
|
||||
cb();
|
||||
};
|
||||
sframeChan.on('Q_UPLOAD_FILE', function (data, cb) {
|
||||
onFileUpload(sframeChan, data, cb);
|
||||
});
|
||||
|
||||
var FP = {};
|
||||
var initFilePicker = function () {
|
||||
var config = {};
|
||||
config.onFilePicked = function (data) {
|
||||
sframeChan.event('EV_FILE_PICKED', data);
|
||||
};
|
||||
config.onClose = function () {
|
||||
FP.$iframe.hide();
|
||||
};
|
||||
config.onFileUpload = onFileUpload;
|
||||
if (!FP.$iframe) {
|
||||
FP.$iframe = $('<iframe>', {id: 'sbox-filePicker-iframe'}).appendTo($('body'));
|
||||
FP.picker = FilePicker.create(config);
|
||||
} else {
|
||||
FP.$iframe.show();
|
||||
FP.picker.refresh();
|
||||
}
|
||||
};
|
||||
sframeChan.on('EV_FILE_PICKER_OPEN', function () {
|
||||
initFilePicker();
|
||||
});
|
||||
|
||||
CpNfOuter.start({
|
||||
|
|
|
@ -56,6 +56,8 @@ define([
|
|||
funcs.createUserAdminMenu = UI.createUserAdminMenu;
|
||||
funcs.displayAvatar = UI.displayAvatar;
|
||||
funcs.createFileDialog = UI.createFileDialog;
|
||||
funcs.initFilePicker = UI.initFilePicker;
|
||||
funcs.openFilePicker = UI.openFilePicker;
|
||||
|
||||
// History
|
||||
funcs.getHistory = function (config) { return History.create(funcs, config); };
|
||||
|
@ -200,6 +202,30 @@ define([
|
|||
}, {accept: data ? data.accept : undefined}));
|
||||
}
|
||||
break;
|
||||
case 'upload':
|
||||
button = $('<button>', {
|
||||
'class': 'btn btn-primary new',
|
||||
title: Messages.uploadButtonTitle,
|
||||
}).append($('<span>', {'class':'fa fa-upload'})).append(' '+Messages.uploadButton);
|
||||
if (!data.FM) { return; }
|
||||
var $input = $('<input>', {
|
||||
'type': 'file',
|
||||
'style': 'display: none;'
|
||||
}).on('change', function (e) {
|
||||
var file = e.target.files[0];
|
||||
var ev = {
|
||||
target: data.target
|
||||
};
|
||||
if (data.filter && !data.filter(file)) {
|
||||
Cryptpad.log('TODO: invalid avatar (type or size)');
|
||||
return;
|
||||
}
|
||||
data.FM.handleFile(file, ev);
|
||||
if (callback) { callback(); }
|
||||
});
|
||||
if (data.accept) { $input.attr('accept', data.accept); }
|
||||
button.click(function () { $input.click(); });
|
||||
break;
|
||||
case 'template':
|
||||
if (!AppConfig.enableTemplates) { return; }
|
||||
button = $('<button>', {
|
||||
|
|
|
@ -89,6 +89,14 @@ define({
|
|||
'Q_GET_PAD_ATTRIBUTE': true,
|
||||
'Q_SET_PAD_ATTRIBUTE': true,
|
||||
|
||||
// Open/close the File picker (sent from the iframe to the outside)
|
||||
'EV_FILE_PICKER_OPEN': true,
|
||||
'EV_FILE_PICKER_CLOSE': true,
|
||||
'EV_FILE_PICKER_REFRESH': true,
|
||||
// File selected in the file picker: sent from the filepicker iframe to the outside
|
||||
// and then send to the inner iframe
|
||||
'EV_FILE_PICKED': true,
|
||||
|
||||
// Get all the files from the drive to display them in a file picker secure app
|
||||
'Q_GET_FILES_LIST': true,
|
||||
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="height: 100%;">
|
||||
<html style="height: 100%; background: transparent;">
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<script async data-bootload="/filepicker/inner.js" data-main="/common/sframe-boot.js?ver=1.1" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
|
||||
<style> .loading-hidden { display: none; } </style>
|
||||
<style>
|
||||
.loading-hidden { display: none; }
|
||||
body #loading {
|
||||
position: absolute;
|
||||
top: 15vh;
|
||||
bottom: 15vh;
|
||||
left: 10vw;
|
||||
right: 10vw;
|
||||
z-index: 200000;
|
||||
overflow: hidden;
|
||||
}
|
||||
body #loading .loadingContainer {
|
||||
margin-top: 35vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body style="background: transparent;">
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -34,9 +34,35 @@ define([
|
|||
var andThen = function (common) {
|
||||
//var metadataMgr = common.getMetadataMgr();
|
||||
var $body = $('body');
|
||||
var sframeChan = common.getSframeChannel();
|
||||
|
||||
var onFilePicked = function (data) {
|
||||
var parsed = Cryptpad.parsePadUrl(data.url);
|
||||
var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel);
|
||||
var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName;
|
||||
sframeChan.event("EV_FILE_PICKED", {
|
||||
src: src,
|
||||
key: parsed.hashData.key
|
||||
});
|
||||
};
|
||||
|
||||
var fmConfig = {
|
||||
body: $('body'),
|
||||
noHandlers: true,
|
||||
onUploaded: function (ev, data) {
|
||||
onFilePicked(data);
|
||||
}
|
||||
};
|
||||
APP.FM = common.createFileManager(fmConfig);
|
||||
var cfg = {
|
||||
$body: $body,
|
||||
common: common
|
||||
common: common,
|
||||
onSelect: function (url) {
|
||||
onFilePicked({url: url});
|
||||
},
|
||||
data: {
|
||||
FM: APP.FM
|
||||
}
|
||||
};
|
||||
common.createFileDialog(cfg);
|
||||
Cryptpad.removeLoadingScreen();
|
||||
|
|
|
@ -7,7 +7,9 @@ define([
|
|||
], function (nThen, ApiConfig, $, RequireConfig) {
|
||||
var requireConfig = RequireConfig();
|
||||
|
||||
var create = function (config) {
|
||||
// Loaded in load #2
|
||||
var sframeChan;
|
||||
nThen(function (waitFor) {
|
||||
$(waitFor());
|
||||
}).nThen(function (waitFor) {
|
||||
|
@ -18,7 +20,7 @@ define([
|
|||
};
|
||||
window.rc = requireConfig;
|
||||
window.apiconf = ApiConfig;
|
||||
$('#sbox-iframe').attr('src',
|
||||
$('#sbox-filePicker-iframe').attr('src',
|
||||
ApiConfig.httpSafeOrigin + '/filepicker/inner.html?' + requireConfig.urlArgs +
|
||||
'#' + encodeURIComponent(JSON.stringify(req)));
|
||||
|
||||
|
@ -38,7 +40,6 @@ define([
|
|||
var Cryptpad;
|
||||
var Crypto;
|
||||
var Cryptget;
|
||||
var sframeChan;
|
||||
|
||||
nThen(function (waitFor) {
|
||||
// Load #2, the loading screen is up so grab whatever you need...
|
||||
|
@ -51,7 +52,7 @@ define([
|
|||
Cryptpad = _Cryptpad;
|
||||
Crypto = _Crypto;
|
||||
Cryptget = _Cryptget;
|
||||
SFrameChannel.create($('#sbox-iframe')[0].contentWindow, waitFor(function (sfc) {
|
||||
SFrameChannel.create($('#sbox-filePicker-iframe')[0].contentWindow, waitFor(function (sfc) {
|
||||
sframeChan = sfc;
|
||||
}));
|
||||
Cryptpad.ready(waitFor());
|
||||
|
@ -117,6 +118,7 @@ define([
|
|||
});
|
||||
|
||||
sframeChan.on('Q_GET_FILES_LIST', function (data, cb) {
|
||||
console.error("TODO: make sure Q_GET_FILES_LIST is only available from filepicker");
|
||||
Cryptpad.getSecureFilesList(function (err, data) {
|
||||
cb({
|
||||
error: err,
|
||||
|
@ -124,6 +126,29 @@ define([
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
sframeChan.on('EV_FILE_PICKER_CLOSE', function () {
|
||||
console.log('close file picker;..');
|
||||
config.onClose();
|
||||
});
|
||||
sframeChan.on('EV_FILE_PICKED', function (data) {
|
||||
config.onFilePicked(data);
|
||||
console.log(data);
|
||||
});
|
||||
sframeChan.on('Q_UPLOAD_FILE', function (data, cb) {
|
||||
config.onFileUpload(sframeChan, data, cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
var refresh = function () {
|
||||
if (!sframeChan) { return; }
|
||||
sframeChan.event('EV_FILE_PICKER_REFRESH');
|
||||
};
|
||||
return {
|
||||
refresh: refresh
|
||||
};
|
||||
};
|
||||
return {
|
||||
create: create
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue