Show only save file dialog when clicking public file link

For #390
This commit is contained in:
Yuya Ochiai 2017-04-27 22:45:32 +09:00
parent 43725f42ff
commit 95c574eadc
3 changed files with 68 additions and 2 deletions

View file

@ -64,9 +64,14 @@ const MattermostView = React.createClass({
ipcRenderer.send('confirm-protocol', destURL.protocol, e.url); ipcRenderer.send('confirm-protocol', destURL.protocol, e.url);
return; return;
} }
if (currentURL.host === destURL.host) { if (currentURL.host === destURL.host) {
// New window should disable nodeIntergration. if (destURL.path.match(/^\/api\/v[3-4]\/public\/files\//)) {
window.open(e.url, 'Mattermost', 'nodeIntegration=no, show=yes'); ipcRenderer.send('download-url', e.url);
} else {
// New window should disable nodeIntergration.
window.open(e.url, 'Mattermost', 'nodeIntegration=no, show=yes');
}
} else { } else {
// if the link is external, use default browser. // if the link is external, use default browser.
shell.openExternal(e.url); shell.openExternal(e.url);

View file

@ -61,6 +61,7 @@ var certificateStore = require('./main/certificateStore').load(path.resolve(app.
const {createMainWindow} = require('./main/mainWindow'); const {createMainWindow} = require('./main/mainWindow');
const appMenu = require('./main/menus/app'); const appMenu = require('./main/menus/app');
const trayMenu = require('./main/menus/tray'); const trayMenu = require('./main/menus/tray');
const downloadURL = require('./main/downloadURL');
const allowProtocolDialog = require('./main/allowProtocolDialog'); const allowProtocolDialog = require('./main/allowProtocolDialog');
const assetsDir = path.resolve(app.getAppPath(), 'assets'); const assetsDir = path.resolve(app.getAppPath(), 'assets');
@ -323,6 +324,14 @@ app.on('login', (event, webContents, request, authInfo, callback) => {
allowProtocolDialog.init(mainWindow); allowProtocolDialog.init(mainWindow);
ipcMain.on('download-url', (event, URL) => {
downloadURL(mainWindow, URL, (err) => {
if (err) {
console.log(err);
}
});
});
// This method will be called when Electron has finished // This method will be called when Electron has finished
// initialization and is ready to create browser windows. // initialization and is ready to create browser windows.
app.on('ready', () => { app.on('ready', () => {

52
src/main/downloadURL.js Normal file
View file

@ -0,0 +1,52 @@
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const electron = require('electron');
const {app, dialog} = electron;
function downloadURL(browserWindow, URL, callback) {
const {net} = electron;
const request = net.request(URL);
request.setHeader('Accept-Encoding', 'gzip,deflate');
request.on('response', (response) => {
const file = getAttachmentName(response.headers);
const dialogOptions = {
defaultPath: path.join(app.getPath('downloads'), file)
};
dialog.showSaveDialog(browserWindow, dialogOptions, (filename) => {
if (filename) {
saveResponseBody(response, filename, callback);
}
});
}).on('error', callback);
request.end();
}
function getAttachmentName(headers) {
if (headers['content-disposition']) {
const contentDisposition = headers['content-disposition'][0];
const matched = contentDisposition.match(/filename="(.*)"/);
if (matched) {
return path.basename(matched[1]);
}
}
return '';
}
function saveResponseBody(response, filename, callback) {
const output = fs.createWriteStream(filename);
output.on('close', callback).on('error', callback);
switch (response.headers['content-encoding']) {
case 'gzip':
response.pipe(zlib.createGunzip()).pipe(output).on('error', callback);
break;
case 'deflate':
response.pipe(zlib.createInflate()).pipe(output).on('error', callback);
break;
default:
response.pipe(output).on('error', callback);
break;
}
}
module.exports = downloadURL;