diff --git a/README.md b/README.md
index 34e6dcef..ac01d549 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
## What it does
-A P2P file sharing experiment which allows you to send encrypted files to other users.
+A file sharing experiment which allows you to send encrypted files to other users.
## Requirements
@@ -48,20 +48,3 @@ Pull requests are always welcome! Feel free to check out the list of ["good firs
## License
[Mozilla Public License Version 2.0](LICENSE)
-
- **Entypo**
-
- Copyright (C) 2012 by Daniel Bruce
-
- Author: Daniel Bruce
- License: SIL (http://scripts.sil.org/OFL)
- Homepage: http://www.entypo.com
-
-
- **Font Awesome**
-
- Copyright (C) 2016 by Dave Gandy
-
- Author: Dave Gandy
- License: SIL ()
- Homepage: http://fortawesome.github.com/Font-Awesome/
diff --git a/docs/faq.md b/docs/faq.md
new file mode 100644
index 00000000..ed15323f
--- /dev/null
+++ b/docs/faq.md
@@ -0,0 +1,32 @@
+## How big of a file can I transfer with Firefox Send?
+
+There is a 2GB file size limit built in to Send, however, in practice you may
+be unable to send files that large. Send encrypts and decrypts the files in
+the browser which is great for security but will tax your system resources. In
+particular you can expect to see your memory usage go up by at least the size
+of the file when the transfer is processing. You can see [the results of some
+testing](https://github.com/mozilla/send/issues/170#issuecomment-314107793).
+For the most reliable operation on common computers, it’s probably best to stay
+under a few hundred megabytes.
+
+## Why is my browser not supported?
+
+We’re using the [Web Cryptography JavaScript API with the AES-GCM
+algorithm](https://www.w3.org/TR/WebCryptoAPI/#aes-gcm) for our encryption.
+Many browsers support this standard and should work fine, but some have not
+implemented it yet (mobile browsers lag behind on this, in
+particular).
+
+## How long are files available for?
+
+Files are available to be downloaded for 24 hours, after which they are removed
+from the server. They are also removed immediately after a download completes.
+
+## Can a file be downloaded more than once?
+
+Not currently, but we're considering multiple download support in a future
+release.
+
+
+*Disclaimer: Send is an experiment and under active development. The answers
+here may change as we get feedback from you and the project matures.*
diff --git a/frontend/src/download.js b/frontend/src/download.js
index 1fe6f7d5..8e211fc8 100644
--- a/frontend/src/download.js
+++ b/frontend/src/download.js
@@ -6,9 +6,9 @@ require('jquery-circle-progress');
const Raven = window.Raven;
$(document).ready(function() {
$('#download-progress').hide();
- $('.send-new').click(() => {
- window.location.replace(`${window.location.origin}`);
- });
+ //link back to homepage
+ $('.send-new').attr('href', window.location.origin);
+
const filename = $('#dl-filename').html();
//initiate progress bar
@@ -21,7 +21,6 @@ $(document).ready(function() {
$('#download-btn').click(download);
function download() {
const fileReceiver = new FileReceiver();
- const name = document.createElement('p');
fileReceiver.on('progress', progress => {
$('#download-page-one').hide();
@@ -86,7 +85,6 @@ $(document).ready(function() {
return;
})
.then(([decrypted, fname]) => {
- name.innerText = fname;
const dataView = new DataView(decrypted);
const blob = new Blob([dataView]);
const downloadUrl = URL.createObjectURL(blob);
diff --git a/frontend/src/fileSender.js b/frontend/src/fileSender.js
index 44240625..a16b1849 100644
--- a/frontend/src/fileSender.js
+++ b/frontend/src/fileSender.js
@@ -8,6 +8,7 @@ class FileSender extends EventEmitter {
super();
this.file = file;
this.iv = window.crypto.getRandomValues(new Uint8Array(12));
+ this.uploadXHR = new XMLHttpRequest();
}
static delete(fileId, token) {
@@ -35,6 +36,10 @@ class FileSender extends EventEmitter {
});
}
+ cancel() {
+ this.uploadXHR.abort();
+ }
+
upload() {
const self = this;
self.emit('loading', true);
@@ -103,7 +108,7 @@ class FileSender extends EventEmitter {
const fd = new FormData();
fd.append('data', blob, file.name);
- const xhr = new XMLHttpRequest();
+ const xhr = self.uploadXHR;
xhr.upload.addEventListener('progress', e => {
if (e.lengthComputable) {
diff --git a/frontend/src/upload.js b/frontend/src/upload.js
index beea5f62..ea29668e 100644
--- a/frontend/src/upload.js
+++ b/frontend/src/upload.js
@@ -47,7 +47,7 @@ $(document).ready(function() {
//disable button for 3s
$copyBtn.attr('disabled', true);
$('#link').attr('disabled', true);
- $copyBtn.html('');
+ $copyBtn.html('');
window.setTimeout(() => {
$copyBtn.attr('disabled', false);
$('#link').attr('disabled', false);
@@ -68,19 +68,10 @@ $(document).ready(function() {
fill: '#3B9DFF',
size: 158
});
- // link back to home page
- $('.send-new').click(() => {
- $('#upload-progress').hide();
- $('#share-link').hide();
- $('#upload-error').hide();
- $copyBtn.attr('disabled', false);
- $('#link').attr('disabled', false);
- $copyBtn.attr('data-l10n-id', 'copyUrlFormButton');
- $('.upload-window').removeClass('ondrag');
- $('#page-one').show();
- });
- //cancel the upload
- $('#cancel-upload').click(() => {});
+
+ //link back to homepage
+ $('.send-new').attr('href', window.location);
+
// on file upload by browse or drag & drop
function onUpload(event) {
event.preventDefault();
@@ -93,6 +84,12 @@ $(document).ready(function() {
const expiration = 24 * 60 * 60 * 1000; //will eventually come from a field
const fileSender = new FileSender(file);
+ $('#cancel-upload').click(() => {
+ fileSender.cancel();
+ location.reload();
+ notify('Your upload was cancelled.');
+ });
+
fileSender.on('progress', progress => {
$('#page-one').hide();
$('#upload-error').hide();
@@ -104,19 +101,19 @@ $(document).ready(function() {
$('.percent-number').html(`${Math.floor(percent * 100)}`);
});
if (progress[1] < 1000000) {
- $('.progress-text').html(
+ $('.progress-text').text(
`${file.name} (${(progress[0] / 1000).toFixed(
1
)}KB of ${(progress[1] / 1000).toFixed(1)}KB)`
);
} else if (progress[1] < 1000000000) {
- $('.progress-text').html(
+ $('.progress-text').text(
`${file.name} (${(progress[0] / 1000000).toFixed(
1
)}MB of ${(progress[1] / 1000000).toFixed(1)}MB)`
);
} else {
- $('.progress-text').html(
+ $('.progress-text').text(
`${file.name} (${(progress[0] / 1000000).toFixed(
1
)}MB of ${(progress[1] / 1000000000).toFixed(1)}GB)`
@@ -219,13 +216,16 @@ $(document).ready(function() {
const row = document.createElement('tr');
const name = document.createElement('td');
const link = document.createElement('td');
+ const $copyIcon = $('', { src: '/resources/copy-16.svg', class: 'icon-copy', title: 'Copy URL' });
const expiry = document.createElement('td');
const del = document.createElement('td');
+ const $delIcon = $('', { src: '/resources/close-16.svg', class: 'icon-delete', title: 'Delete' });
const popupDiv = document.createElement('div');
const $popupText = $('
', { class: 'popuptext' });
const cellText = document.createTextNode(file.name);
const url = file.url.trim() + `#${file.secretKey}`.trim();
+
$('#link').attr('value', url);
$('#copy-text').attr(
'data-l10n-args',
@@ -252,8 +252,9 @@ $(document).ready(function() {
link.appendChild(linkSpan);
link.style.color = '#0A8DFF';
+
//copy link to clipboard when icon clicked
- $(link).click(function() {
+ $copyIcon.click(function() {
const aux = document.createElement('input');
aux.setAttribute('value', url);
document.body.appendChild(aux);
@@ -265,10 +266,11 @@ $(document).ready(function() {
link.innerHTML = translated;
})
window.setTimeout(() => {
- const linkSpan = document.createElement('span');
- $(linkSpan).addClass('icon-docs');
- $(linkSpan).attr('data-l10n-id', 'copyUrlHover');
- $(link).html(linkSpan);
+ const linkImg = document.createElement('img');
+ $(linkImg).addClass('icon-copy');
+ $(linkImg).attr('data-l10n-id', 'copyUrlHover');
+ $(linkImg).attr('src', '/resources/copy-16.svg');
+ $(link).html(linkImg);
}, 500);
});
@@ -325,9 +327,22 @@ $(document).ready(function() {
$popupText.html([
popupDelSpan,
' ',
+ ' ',
popupNvmSpan
]);
+
+ // add data cells to table row
+ row.appendChild(name);
+ $(link).append($copyIcon);
+ row.appendChild(link);
+ row.appendChild(expiry);
+ $(popupDiv).append($popupText);
+ $(del).append($delIcon);
+ del.appendChild(popupDiv);
+ row.appendChild(del);
+ $('tbody').append(row); //add row to table
+
// delete file
$popupText.find('.del-file').click(e => {
FileSender.delete(file.fileId, file.deleteToken).then(() => {
@@ -342,17 +357,8 @@ $(document).ready(function() {
location.reload();
});
};
-
- // add data cells to table row
- row.appendChild(name);
- row.appendChild(link);
- row.appendChild(expiry);
- $(popupDiv).append($popupText);
- del.appendChild(popupDiv);
- row.appendChild(del);
-
// show popup
- del.addEventListener('click', function() {
+ $delIcon.click(function() {
$popupText.addClass('show');
$popupText.focus();
});
@@ -368,7 +374,7 @@ $(document).ready(function() {
$popupText.blur(() => {
$popupText.removeClass('show');
});
- $('tbody').append(row); //add row to table
+
toggleHeader();
}
diff --git a/public/contribute.json b/public/contribute.json
index b7b1ab26..db85d7a2 100644
--- a/public/contribute.json
+++ b/public/contribute.json
@@ -22,7 +22,6 @@
"JavaScript",
"jQuery",
"Node",
- "P2P",
"Redis"
]
}
diff --git a/public/main.css b/public/main.css
index 02a1f69a..129342d9 100644
--- a/public/main.css
+++ b/public/main.css
@@ -24,7 +24,7 @@ body {
.all {
padding-top: 10%;
- overflow-y: scroll;
+ padding-bottom: 51px;
}
input, select, textarea, button {
@@ -35,10 +35,6 @@ a {
text-decoration: none;
}
-span {
- cursor: pointer;
-}
-
/** page-one **/
.title {
font-size: 33px;
@@ -72,8 +68,9 @@ span {
.upload-window.ondrag {
border: 3px dashed rgba(0, 148, 251, 0.5);
margin: 0 auto;
- width: 672px;
- height: 267px;
+ width: 636px;
+ height: 251px;
+ transform: scale(1.05);
border-radius: 4.2px;
display: flex;
justify-content: center;
@@ -146,6 +143,10 @@ tbody {
table-layout: fixed;
}
+.icon-delete, .icon-copy, .icon-check {
+ cursor: pointer;
+}
+
/* Popup container */
.popup {
position: relative;
@@ -166,7 +167,7 @@ tbody {
z-index: 1;
bottom: 20px;
left: 50%;
- margin-left: -96px;
+ margin-left: -88px;
transition: opacity 0.5s;
opacity: 0;
outline: 0;
diff --git a/public/resources/check-16.svg b/public/resources/check-16.svg
new file mode 100644
index 00000000..4243e0dc
--- /dev/null
+++ b/public/resources/check-16.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/resources/close-16.svg b/public/resources/close-16.svg
new file mode 100644
index 00000000..8f143c5b
--- /dev/null
+++ b/public/resources/close-16.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/resources/copy-16.svg b/public/resources/copy-16.svg
new file mode 100644
index 00000000..c5cee826
--- /dev/null
+++ b/public/resources/copy-16.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/resources/firefox_logo-only.svg b/public/resources/firefox_logo-only.svg
index 6c9d5ce3..4f3cbbb5 100644
--- a/public/resources/firefox_logo-only.svg
+++ b/public/resources/firefox_logo-only.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/resources/fontello-24c5e6ad/config.json b/public/resources/fontello-24c5e6ad/config.json
deleted file mode 100755
index 3a91a711..00000000
--- a/public/resources/fontello-24c5e6ad/config.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "",
- "css_prefix_text": "icon-",
- "css_use_suffix": false,
- "hinting": true,
- "units_per_em": 1000,
- "ascent": 850,
- "glyphs": [
- {
- "uid": "c8585e1e5b0467f28b70bce765d5840c",
- "css": "docs",
- "code": 61637,
- "src": "fontawesome"
- },
- {
- "uid": "c709da589c923ba3c2ad48d9fc563e93",
- "css": "cancel-1",
- "code": 59393,
- "src": "entypo"
- },
- {
- "uid": "14017aae737730faeda4a6fd8fb3a5f0",
- "css": "check",
- "code": 59394,
- "src": "entypo"
- }
- ]
-}
\ No newline at end of file
diff --git a/public/resources/fontello-24c5e6ad/css/fontello.css b/public/resources/fontello-24c5e6ad/css/fontello.css
deleted file mode 100755
index ea18ff91..00000000
--- a/public/resources/fontello-24c5e6ad/css/fontello.css
+++ /dev/null
@@ -1,60 +0,0 @@
-@font-face {
- font-family: 'fontello';
- src: url('../font/fontello.eot?60405031');
- src: url('../font/fontello.eot?60405031#iefix') format('embedded-opentype'),
- url('../font/fontello.woff2?60405031') format('woff2'),
- url('../font/fontello.woff?60405031') format('woff'),
- url('../font/fontello.ttf?60405031') format('truetype'),
- url('../font/fontello.svg?60405031#fontello') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
-/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
-/*
-@media screen and (-webkit-min-device-pixel-ratio:0) {
- @font-face {
- font-family: 'fontello';
- src: url('../font/fontello.svg?60405031#fontello') format('svg');
- }
-}
-*/
-
- [class^="icon-"]:before, [class*=" icon-"]:before {
- font-family: "fontello";
- font-style: normal;
- font-weight: normal;
- speak: none;
-
- display: inline-block;
- text-decoration: inherit;
- width: 1em;
- margin-right: .2em;
- text-align: center;
- /* opacity: .8; */
-
- /* For safety - reset parent styles, that can break glyph codes*/
- font-variant: normal;
- text-transform: none;
-
- /* fix buttons height, for twitter bootstrap */
- line-height: 1em;
-
- /* Animation center compensation - margins should be symmetric */
- /* remove if not needed */
- margin-left: .2em;
-
- /* you can be more comfortable with increased icons size */
- /* font-size: 120%; */
-
- /* Font smoothing. That was taken from TWBS */
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-
- /* Uncomment for 3D effect */
- /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
-}
-
-.icon-cancel-1:before { content: '\e801'; font-size: 1.5em; font-weight: lighter;} /* '' */
-.icon-check:before { content: '\e802'; font-size: 1.5em;} /* '' */
-.icon-docs:before { content: '\f0c5'; font-weight: bolder;} /* '' */
diff --git a/public/resources/fontello-24c5e6ad/font/fontello.eot b/public/resources/fontello-24c5e6ad/font/fontello.eot
deleted file mode 100755
index 30b0ddc1..00000000
Binary files a/public/resources/fontello-24c5e6ad/font/fontello.eot and /dev/null differ
diff --git a/public/resources/fontello-24c5e6ad/font/fontello.svg b/public/resources/fontello-24c5e6ad/font/fontello.svg
deleted file mode 100755
index 431b9d7c..00000000
--- a/public/resources/fontello-24c5e6ad/font/fontello.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/public/resources/fontello-24c5e6ad/font/fontello.ttf b/public/resources/fontello-24c5e6ad/font/fontello.ttf
deleted file mode 100755
index 86b99e44..00000000
Binary files a/public/resources/fontello-24c5e6ad/font/fontello.ttf and /dev/null differ
diff --git a/public/resources/fontello-24c5e6ad/font/fontello.woff b/public/resources/fontello-24c5e6ad/font/fontello.woff
deleted file mode 100755
index 25766584..00000000
Binary files a/public/resources/fontello-24c5e6ad/font/fontello.woff and /dev/null differ
diff --git a/public/resources/fontello-24c5e6ad/font/fontello.woff2 b/public/resources/fontello-24c5e6ad/font/fontello.woff2
deleted file mode 100755
index ca749888..00000000
Binary files a/public/resources/fontello-24c5e6ad/font/fontello.woff2 and /dev/null differ
diff --git a/public/resources/github-icon.svg b/public/resources/github-icon.svg
index 977cf9d7..44e074c8 100644
--- a/public/resources/github-icon.svg
+++ b/public/resources/github-icon.svg
@@ -1,59 +1 @@
-
-
-
-
+
\ No newline at end of file
diff --git a/public/resources/illustration_download.svg b/public/resources/illustration_download.svg
index 85e8c5b9..9425fc28 100644
--- a/public/resources/illustration_download.svg
+++ b/public/resources/illustration_download.svg
@@ -1,126 +1 @@
-
-
-
+
\ No newline at end of file
diff --git a/public/resources/illustration_error.svg b/public/resources/illustration_error.svg
index ca44824d..cba8d2e0 100644
--- a/public/resources/illustration_error.svg
+++ b/public/resources/illustration_error.svg
@@ -1,93 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/resources/illustration_expired.svg b/public/resources/illustration_expired.svg
index 9c551a28..1d569f08 100644
--- a/public/resources/illustration_expired.svg
+++ b/public/resources/illustration_expired.svg
@@ -1,64 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/resources/mozilla-logo.svg b/public/resources/mozilla-logo.svg
index 13e0a1c3..3ea2e868 100644
--- a/public/resources/mozilla-logo.svg
+++ b/public/resources/mozilla-logo.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/public/resources/send_bg.svg b/public/resources/send_bg.svg
index f92ac6d5..8a2a63bb 100644
--- a/public/resources/send_bg.svg
+++ b/public/resources/send_bg.svg
@@ -1,107 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/resources/send_logo.svg b/public/resources/send_logo.svg
index af6c16f5..e370560d 100644
--- a/public/resources/send_logo.svg
+++ b/public/resources/send_logo.svg
@@ -1,21 +1 @@
-
-
+
\ No newline at end of file
diff --git a/public/resources/send_logo_type.svg b/public/resources/send_logo_type.svg
index fc8f9ada..07091885 100644
--- a/public/resources/send_logo_type.svg
+++ b/public/resources/send_logo_type.svg
@@ -1,14 +1 @@
-
-
+
\ No newline at end of file
diff --git a/public/resources/twitter-icon.svg b/public/resources/twitter-icon.svg
index 0b61e76e..8816009a 100644
--- a/public/resources/twitter-icon.svg
+++ b/public/resources/twitter-icon.svg
@@ -1,46 +1 @@
-
-
-
+
\ No newline at end of file
diff --git a/public/resources/upload.svg b/public/resources/upload.svg
index e9bb7fc2..f98e6b2e 100644
--- a/public/resources/upload.svg
+++ b/public/resources/upload.svg
@@ -1,24 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/server/server.js b/server/server.js
index b26cde12..e599e681 100644
--- a/server/server.js
+++ b/server/server.js
@@ -224,6 +224,19 @@ app.post('/upload', (req, res, next) => {
});
});
});
+
+ req.on('close', err => {
+ storage
+ .forceDelete(newId)
+ .then(err => {
+ if (!err) {
+ log.info('Deleted:', newId);
+ }
+ })
+ .catch(err => {
+ log.info('DeleteError:', newId);
+ });
+ })
});
app.get('/__lbheartbeat__', (req, res) => {
diff --git a/server/storage.js b/server/storage.js
index 5d48b490..68375e47 100644
--- a/server/storage.js
+++ b/server/storage.js
@@ -234,13 +234,13 @@ function awsDelete(id, delete_token) {
if (!reply || delete_token !== reply) {
reject();
} else {
- redis_client.del(id);
const params = {
Bucket: conf.s3_bucket,
Key: id
};
s3.deleteObject(params, function(err, _data) {
+ redis_client.del(id);
err ? reject(err) : resolve(err);
});
}
@@ -250,13 +250,13 @@ function awsDelete(id, delete_token) {
function awsForceDelete(id) {
return new Promise((resolve, reject) => {
- redis_client.del(id);
const params = {
Bucket: conf.s3_bucket,
Key: id
};
s3.deleteObject(params, function(err, _data) {
+ redis_client.del(id);
err ? reject(err) : resolve(err);
});
});
diff --git a/views/download.handlebars b/views/download.handlebars
index 15bd5f2d..f6eb8cf1 100644
--- a/views/download.handlebars
+++ b/views/download.handlebars
@@ -1,52 +1,46 @@
-