mirror of
https://gitlab.com/timvisee/send.git
synced 2025-12-07 22:50:53 +03:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cedc6e014 | ||
|
|
590b56dd92 | ||
|
|
62809fb57d | ||
|
|
44c03e355f | ||
|
|
d305e7fd57 | ||
|
|
33064484c4 | ||
|
|
283df64542 | ||
|
|
e8c49962da | ||
|
|
2ec69ec927 | ||
|
|
7eb2ea02c1 | ||
|
|
e4950f6c68 | ||
|
|
9f2d248e8f | ||
|
|
5d1ede5f63 | ||
|
|
47666c153a | ||
|
|
cadf039c55 | ||
|
|
dbe374bdc6 | ||
|
|
48ab1cdd4e | ||
|
|
54150702da | ||
|
|
981f86946b | ||
|
|
b5865f00e9 | ||
|
|
7797f485f2 | ||
|
|
db169cb9f0 | ||
|
|
f999c4c44f | ||
|
|
e9b50b7682 | ||
|
|
a3e8646ea7 | ||
|
|
a6a3cae5e9 | ||
|
|
8d80ba1f69 | ||
|
|
e5f76a7b1f | ||
|
|
acf82a4e3e | ||
|
|
0acdf3a720 | ||
|
|
305dd2f5ef | ||
|
|
e53571e219 | ||
|
|
0eda8d2082 | ||
|
|
1cd4adfc2a | ||
|
|
0460bd2e97 | ||
|
|
60146541f2 | ||
|
|
79d314146b | ||
|
|
72d12c3d80 | ||
|
|
1469464c43 | ||
|
|
7cdef4bbfc | ||
|
|
24aa1f2e17 |
@@ -4,4 +4,5 @@ firefox
|
|||||||
coverage
|
coverage
|
||||||
android/app/build
|
android/app/build
|
||||||
app/locale.js
|
app/locale.js
|
||||||
app/capabilities.js
|
app/capabilities.js
|
||||||
|
app/qrcode.js
|
||||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -1,2 +0,0 @@
|
|||||||
{
|
|
||||||
}
|
|
||||||
59
CONTRIBUTORS
59
CONTRIBUTORS
@@ -1,8 +1,14 @@
|
|||||||
|
Abd ar-Rahman Hamidi
|
||||||
Abdalrahman Hwoij
|
Abdalrahman Hwoij
|
||||||
|
Abdulrash6211
|
||||||
|
Abdulrasheed Idris
|
||||||
|
Abelardo Ayala Rodríguez
|
||||||
Abhinav Adduri
|
Abhinav Adduri
|
||||||
|
Adaobi
|
||||||
Adnan Kičin
|
Adnan Kičin
|
||||||
Adolfo Jayme Barrientos
|
Adolfo Jayme Barrientos
|
||||||
Alberto Castro
|
Alberto Castro
|
||||||
|
Alexander Parada
|
||||||
Alexander Slovesnik
|
Alexander Slovesnik
|
||||||
Alfredos-Panagiotis Damkalis
|
Alfredos-Panagiotis Damkalis
|
||||||
Aman Alam
|
Aman Alam
|
||||||
@@ -14,9 +20,12 @@ Anika Dorn
|
|||||||
Anish Sheela
|
Anish Sheela
|
||||||
Arash Mousavi
|
Arash Mousavi
|
||||||
Artem Polivanchuk
|
Artem Polivanchuk
|
||||||
|
Ashesh Vidyut
|
||||||
Ashikur Rahman
|
Ashikur Rahman
|
||||||
Ashok kumar
|
Ashok kumar
|
||||||
|
Ayobamiadebayo375
|
||||||
Balasankar C
|
Balasankar C
|
||||||
|
Bald3mar
|
||||||
Balázs Meskó
|
Balázs Meskó
|
||||||
Belayet Hossain
|
Belayet Hossain
|
||||||
Benjamin Forehand Jr
|
Benjamin Forehand Jr
|
||||||
@@ -27,12 +36,14 @@ Boopesh Mahendran
|
|||||||
Brahim Essaidi
|
Brahim Essaidi
|
||||||
Brainlulz
|
Brainlulz
|
||||||
Breana Gonzales
|
Breana Gonzales
|
||||||
|
CLASSIFIED
|
||||||
Christian Elbrianno
|
Christian Elbrianno
|
||||||
Christoph Kührer
|
Christoph Kührer
|
||||||
Christopher Ramírez
|
Christopher Ramírez
|
||||||
Chuck Harmston
|
Chuck Harmston
|
||||||
Cloney 173741
|
Cloney 173741
|
||||||
Cláudio Esperança
|
Cláudio Esperança
|
||||||
|
Connor Ford
|
||||||
Cristian Silaghi
|
Cristian Silaghi
|
||||||
Cynthia Pereira
|
Cynthia Pereira
|
||||||
Daniel Thorn
|
Daniel Thorn
|
||||||
@@ -44,6 +55,7 @@ Dhyey Thakore
|
|||||||
Donovan Preston
|
Donovan Preston
|
||||||
Edi Santoso
|
Edi Santoso
|
||||||
Edmund Huggett
|
Edmund Huggett
|
||||||
|
Eduard Bopp
|
||||||
Elisa X
|
Elisa X
|
||||||
Emily
|
Emily
|
||||||
Emily Hou
|
Emily Hou
|
||||||
@@ -59,12 +71,17 @@ Francesco Lodolo [:flod]
|
|||||||
Frederick Villaluna
|
Frederick Villaluna
|
||||||
G12r
|
G12r
|
||||||
Gabriela
|
Gabriela
|
||||||
|
Garysqo
|
||||||
Gautam krishna.R
|
Gautam krishna.R
|
||||||
George Raptis
|
George Raptis
|
||||||
Georgianizator
|
Georgianizator
|
||||||
|
Gery Escalier
|
||||||
|
Gisela Solis
|
||||||
Gonçalo Matos
|
Gonçalo Matos
|
||||||
Gwenn
|
Gwenn
|
||||||
Hampus
|
Hampus
|
||||||
|
Hmxhmx
|
||||||
|
Hrant
|
||||||
Hugo
|
Hugo
|
||||||
Hugo Abreu
|
Hugo Abreu
|
||||||
Hyeonseok Shin
|
Hyeonseok Shin
|
||||||
@@ -75,26 +92,35 @@ Jae Hyeon Park
|
|||||||
Jakob Kappel
|
Jakob Kappel
|
||||||
Jakub Rychlý
|
Jakub Rychlý
|
||||||
Jamie
|
Jamie
|
||||||
|
Jan Schloß
|
||||||
Jarmo
|
Jarmo
|
||||||
Jim Spentzos
|
Jim Spentzos
|
||||||
Jiri Grönroos
|
Jiri Grönroos
|
||||||
|
Jirka Soukeník
|
||||||
Jobava
|
Jobava
|
||||||
Joe Becher
|
Joe Becher
|
||||||
Joe ST
|
Joe ST
|
||||||
Joergen
|
Joergen
|
||||||
Johann-S
|
Johann-S
|
||||||
John Gruen
|
John Gruen
|
||||||
|
John Zonunmawi Vankal
|
||||||
Jon Buckley
|
Jon Buckley
|
||||||
Jon Vadillo
|
Jon Vadillo
|
||||||
Jonathan Claudius
|
Jonathan Claudius
|
||||||
Jordi Cuevas
|
Jordi Cuevas
|
||||||
Jordi Serratosa
|
Jordi Serratosa
|
||||||
|
Joseph.maza
|
||||||
|
José Manuel
|
||||||
Juan Esteban Ajsivinac Sián
|
Juan Esteban Ajsivinac Sián
|
||||||
|
Juan Pablo
|
||||||
Juan Sián
|
Juan Sián
|
||||||
|
Julio Gomez
|
||||||
Juraj Cigáň
|
Juraj Cigáň
|
||||||
|
Jwtiyar
|
||||||
Kerim Kalamujić
|
Kerim Kalamujić
|
||||||
Khaled Hosny
|
Khaled Hosny
|
||||||
Kim Ludvigsen
|
Kim Ludvigsen
|
||||||
|
Kim YoungCheon
|
||||||
Kim Younggeon
|
Kim Younggeon
|
||||||
Kohei Yoshino
|
Kohei Yoshino
|
||||||
Lan Glad
|
Lan Glad
|
||||||
@@ -103,10 +129,12 @@ Laurent Jouanneau
|
|||||||
Lobodzets
|
Lobodzets
|
||||||
LuFlo
|
LuFlo
|
||||||
Luis A. Sánchez
|
Luis A. Sánchez
|
||||||
|
Luis Flores Martínez
|
||||||
Luiz Carlos de Morais
|
Luiz Carlos de Morais
|
||||||
Luiz Felipe F M Costa
|
Luiz Felipe F M Costa
|
||||||
Luna Jernberg
|
Luna Jernberg
|
||||||
Mahay Alam Khan
|
Mahay Alam Khan
|
||||||
|
Manuela Silva
|
||||||
Marcelo Ghelman
|
Marcelo Ghelman
|
||||||
Marcelo Poli
|
Marcelo Poli
|
||||||
Marco Aurélio
|
Marco Aurélio
|
||||||
@@ -116,16 +144,21 @@ Mark Liang (You-Wen)
|
|||||||
Marko Andrejić
|
Marko Andrejić
|
||||||
Martijn Dekker
|
Martijn Dekker
|
||||||
Marwan Mohamad
|
Marwan Mohamad
|
||||||
|
Mathieu Lecarme
|
||||||
Matjaž Horvat
|
Matjaž Horvat
|
||||||
Maykon Chagas
|
Maykon Chagas
|
||||||
Melo46
|
Melo46
|
||||||
Merike Sell
|
Merike Sell
|
||||||
Michael Köhler
|
Michael Köhler
|
||||||
|
Michael Peter
|
||||||
Michael Wolf
|
Michael Wolf
|
||||||
Michal Stanke
|
Michal Stanke
|
||||||
Michal Vašíček
|
Michal Vašíček
|
||||||
|
Miguel
|
||||||
Mikeyy
|
Mikeyy
|
||||||
|
Milo
|
||||||
Miro Rauhala
|
Miro Rauhala
|
||||||
|
Misael Hernández
|
||||||
Mozilla Pontoon
|
Mozilla Pontoon
|
||||||
Mozilla-GitHub-Standards
|
Mozilla-GitHub-Standards
|
||||||
Mozinet
|
Mozinet
|
||||||
@@ -133,6 +166,7 @@ Moḥend Belqasem
|
|||||||
Muhend Belkacem
|
Muhend Belkacem
|
||||||
Muḥend Belqasem
|
Muḥend Belqasem
|
||||||
Myungjae Won
|
Myungjae Won
|
||||||
|
Netza López
|
||||||
Nicholas Skinsacos
|
Nicholas Skinsacos
|
||||||
Nihad
|
Nihad
|
||||||
Nihad Suljić
|
Nihad Suljić
|
||||||
@@ -144,12 +178,14 @@ Peter deHaan
|
|||||||
Pierre Neter
|
Pierre Neter
|
||||||
Pin-guang Chen
|
Pin-guang Chen
|
||||||
Piotr Drąg
|
Piotr Drąg
|
||||||
|
Pontoon
|
||||||
Quentí
|
Quentí
|
||||||
Quế Tùng
|
Quế Tùng
|
||||||
Rachel Tublitz
|
Rachel Tublitz
|
||||||
Radu Popescu
|
Radu Popescu
|
||||||
Rhoslyn Prys
|
Rhoslyn Prys
|
||||||
RickieES
|
RickieES
|
||||||
|
Ricky Rosario
|
||||||
Rimas Kudelis
|
Rimas Kudelis
|
||||||
Rizky Ariestiyansyah
|
Rizky Ariestiyansyah
|
||||||
Rob Powell
|
Rob Powell
|
||||||
@@ -170,6 +206,7 @@ Sav22999
|
|||||||
Schieck :)
|
Schieck :)
|
||||||
Selim Şumlu
|
Selim Şumlu
|
||||||
Selyan Sliman Amiri
|
Selyan Sliman Amiri
|
||||||
|
Selyan Slimane Amiri
|
||||||
Sidak Singh Aulakh
|
Sidak Singh Aulakh
|
||||||
Slimane Amiri
|
Slimane Amiri
|
||||||
Slimane Selyan AMIRI
|
Slimane Selyan AMIRI
|
||||||
@@ -187,8 +224,11 @@ Ton
|
|||||||
Top
|
Top
|
||||||
Tymur Faradzhev
|
Tymur Faradzhev
|
||||||
Uccen Marzuq
|
Uccen Marzuq
|
||||||
|
Umegbewe
|
||||||
Varghese Thomas
|
Varghese Thomas
|
||||||
Victor Bychek
|
Victor Bychek
|
||||||
|
Victor Davila
|
||||||
|
Victor Ibragimov
|
||||||
Vimal Raghubir
|
Vimal Raghubir
|
||||||
Vitaliy Krutko
|
Vitaliy Krutko
|
||||||
Weihang Lo
|
Weihang Lo
|
||||||
@@ -198,29 +238,42 @@ YFdyh000
|
|||||||
Yassine Aït-El-Mouden
|
Yassine Aït-El-Mouden
|
||||||
Yongmin H
|
Yongmin H
|
||||||
You-Wen Liang (Mark)
|
You-Wen Liang (Mark)
|
||||||
|
Zhenya Tikhonov
|
||||||
|
ZiriSut
|
||||||
aaaaalbert
|
aaaaalbert
|
||||||
|
abtin
|
||||||
|
ada_okeke60
|
||||||
aefgh39622
|
aefgh39622
|
||||||
alamanda
|
alamanda
|
||||||
albertdcastro
|
albertdcastro
|
||||||
alex_mayorga
|
alex_mayorga
|
||||||
|
ali.malek.71
|
||||||
ariestiyansyah
|
ariestiyansyah
|
||||||
avelper
|
avelper
|
||||||
|
biobell2000
|
||||||
|
bulut
|
||||||
chilledfrogs
|
chilledfrogs
|
||||||
clouserw-mozilla-owner
|
clouserw-mozilla-owner
|
||||||
|
dependabot[bot]
|
||||||
dgadelha
|
dgadelha
|
||||||
dskmori
|
dskmori
|
||||||
ehuggett
|
ehuggett
|
||||||
|
elenatambriz
|
||||||
eljuno
|
eljuno
|
||||||
emily-hou1
|
emily-hou1
|
||||||
erdem cobanoglu
|
erdem cobanoglu
|
||||||
|
fcortess
|
||||||
gautamkrishnar
|
gautamkrishnar
|
||||||
gmontagu
|
gmontagu
|
||||||
goofy
|
goofy
|
||||||
hello
|
hello
|
||||||
hi
|
hi
|
||||||
ivan.pompa
|
ivan.pompa
|
||||||
|
jackyzy823
|
||||||
jesferman1993
|
jesferman1993
|
||||||
jlG
|
jlG
|
||||||
|
jnunezf96
|
||||||
|
johngruen
|
||||||
josotrix
|
josotrix
|
||||||
jspam
|
jspam
|
||||||
julen
|
julen
|
||||||
@@ -230,12 +283,15 @@ kumincir
|
|||||||
leo.toneff
|
leo.toneff
|
||||||
m4hdi.pdroid
|
m4hdi.pdroid
|
||||||
mail
|
mail
|
||||||
|
manuel padilla sanchez
|
||||||
manxmensch
|
manxmensch
|
||||||
marigalicer
|
marigalicer
|
||||||
marsf
|
marsf
|
||||||
merianosnikos
|
merianosnikos
|
||||||
|
minvs1
|
||||||
mirzet.omerovic.1992
|
mirzet.omerovic.1992
|
||||||
mujeebcpy
|
mujeebcpy
|
||||||
|
okyanusoz
|
||||||
p.sanroman.bengoetxea
|
p.sanroman.bengoetxea
|
||||||
passionforlife
|
passionforlife
|
||||||
paul.trevor
|
paul.trevor
|
||||||
@@ -249,10 +305,12 @@ robbp
|
|||||||
ruikunai
|
ruikunai
|
||||||
savemore99.sm
|
savemore99.sm
|
||||||
sergio
|
sergio
|
||||||
|
shamanchic2011
|
||||||
shikhar-scs
|
shikhar-scs
|
||||||
siparon
|
siparon
|
||||||
skystar-p
|
skystar-p
|
||||||
stripTM
|
stripTM
|
||||||
|
sugabelly
|
||||||
tatalmondmush
|
tatalmondmush
|
||||||
tiagomoraismorgado
|
tiagomoraismorgado
|
||||||
timvisee
|
timvisee
|
||||||
@@ -261,6 +319,7 @@ xcffl
|
|||||||
ybouhamam
|
ybouhamam
|
||||||
yoshimitsu002
|
yoshimitsu002
|
||||||
yusup.ramdani
|
yusup.ramdani
|
||||||
|
zankomhamad
|
||||||
Μιχάλης
|
Μιχάλης
|
||||||
Марко Костић (Marko Kostić)
|
Марко Костић (Marko Kostić)
|
||||||
Ратко Вујановић
|
Ратко Вујановић
|
||||||
|
|||||||
56
README.md
56
README.md
@@ -1,7 +1,57 @@
|
|||||||
# [](https://gitlab.com/timvisee/send/) Send
|
# [](https://gitlab.com/timvisee/send/) Send
|
||||||
|
|
||||||
Based on Mozilla's [Firefox Send](https://github.com/mozilla/send),
|
[![Build status on GitLab CI][gitlab-ci-master-badge]][gitlab-ci-link]
|
||||||
with branding removed.
|
[![Latest release][release-badge]][release-link]
|
||||||
|
[![Docker image][docker-image-badge]][docker-image-link]
|
||||||
|
[![Project license][repo-license-badge]](LICENSE)
|
||||||
|
|
||||||
|
[docker-image-badge]: https://img.shields.io/badge/docker-latest-blue.svg
|
||||||
|
[docker-image-link]: https://gitlab.com/timvisee/send/container_registry/eyJuYW1lIjoidGltdmlzZWUvc2VuZCIsInRhZ3NfcGF0aCI6Ii90aW12aXNlZS9zZW5kL3JlZ2lzdHJ5L3JlcG9zaXRvcnkvMTQxODUwNC90YWdzP2Zvcm1hdD1qc29uIiwiaWQiOjE0MTg1MDQsImNsZWFudXBfcG9saWN5X3N0YXJ0ZWRfYXQiOm51bGx9
|
||||||
|
[gitlab-ci-link]: https://gitlab.com/timvisee/send/pipelines
|
||||||
|
[gitlab-ci-master-badge]: https://gitlab.com/timvisee/send/badges/master/pipeline.svg
|
||||||
|
[release-badge]: https://img.shields.io/github/v/tag/timvisee/send
|
||||||
|
[release-link]: https://gitlab.com/timvisee/send/-/tags
|
||||||
|
[repo-license-badge]: https://img.shields.io/github/license/timvisee/send.svg
|
||||||
|
|
||||||
|
A fork of Mozilla's [Firefox Send][mozilla-send].
|
||||||
|
Mozilla discontinued Send, this fork is a community effort to keep the project
|
||||||
|
up-to-date and alive.
|
||||||
|
|
||||||
|
- Forked [at][fork-commit] Mozilla's last publicly hosted version
|
||||||
|
- _Mozilla_ & _Firefox_ branding [is][remove-branding-pr] removed so you can legally self-host
|
||||||
|
- Kept compatible with [`ffsend`][ffsend] (CLI for Send)
|
||||||
|
- Dependencies have been updated
|
||||||
|
- Mozilla's [changes][mozilla-patches] since the fork have been selectively [merged][mozilla-patches-pr]
|
||||||
|
- Mozilla's experimental report feature, download tokens, trust warnings and FxA changes are not included
|
||||||
|
|
||||||
|
Find an up-to-date Docker image here: [docs/docker.md](docs/docker.md)
|
||||||
|
|
||||||
|
The original project by Mozilla can be found [here][mozilla-send].
|
||||||
|
The [`mozilla-master`][branch-mozilla-master] branch holds the `master` branch
|
||||||
|
as left by Mozilla.
|
||||||
|
The [`send-v3`][branch-send-v3] branch holds the commit tree of Mozilla's last
|
||||||
|
publicly hosted version, which this fork is based on.
|
||||||
|
The [`send-v4`][branch-send-v4] branch holds the commit tree of Mozilla's last
|
||||||
|
experimental version which was still a work in progress (featuring file
|
||||||
|
reporting, download tokens, trust warnings and FxA changes), this has
|
||||||
|
selectively been merged into this fork.
|
||||||
|
Please consider to [donate][donate] to allow me to keep working on this.
|
||||||
|
|
||||||
|
Thanks [Mozilla][mozilla] for building this amazing tool!
|
||||||
|
|
||||||
|
[branch-mozilla-master]: https://gitlab.com/timvisee/send/-/tree/mozilla-master
|
||||||
|
[branch-send-v3]: https://gitlab.com/timvisee/send/-/tree/send-v3
|
||||||
|
[branch-send-v4]: https://gitlab.com/timvisee/send/-/tree/send-v4
|
||||||
|
[donate]: https://timvisee.com/donate
|
||||||
|
[ffsend]: https://github.com/timvisee/ffsend
|
||||||
|
[fork-commit]: https://gitlab.com/timvisee/send/-/commit/3e9be676413a6e1baaf6a354c180e91899d10bec
|
||||||
|
[mozilla-patches-pr]: https://gitlab.com/timvisee/send/-/merge_requests/3
|
||||||
|
[mozilla-patches]: https://gitlab.com/timvisee/send/-/compare/3e9be676413a6e1baaf6a354c180e91899d10bec...mozilla-master
|
||||||
|
[mozilla-send]: https://github.com/mozilla/send
|
||||||
|
[mozilla]: https://mozilla.org/
|
||||||
|
[remove-branding-pr]: https://gitlab.com/timvisee/send/-/merge_requests/2
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
**Docs:** [FAQ](docs/faq.md), [Encryption](docs/encryption.md), [Build](docs/build.md), [Docker](docs/docker.md), [Metrics](docs/metrics.md), [More](docs/)
|
**Docs:** [FAQ](docs/faq.md), [Encryption](docs/encryption.md), [Build](docs/build.md), [Docker](docs/docker.md), [Metrics](docs/metrics.md), [More](docs/)
|
||||||
|
|
||||||
@@ -109,4 +159,6 @@ The android implementation is contained in the `android` directory, and can be v
|
|||||||
|
|
||||||
[Mozilla Public License Version 2.0](LICENSE)
|
[Mozilla Public License Version 2.0](LICENSE)
|
||||||
|
|
||||||
|
[qrcode.js](https://github.com/kazuhikoarase/qrcode-generator) licensed under MIT
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import FileSender from './fileSender';
|
|
||||||
import FileReceiver from './fileReceiver';
|
|
||||||
import { copyToClipboard, delay, openLinksInNewTab, percent } from './utils';
|
|
||||||
import * as metrics from './metrics';
|
import * as metrics from './metrics';
|
||||||
import { bytes, locale } from './utils';
|
import FileReceiver from './fileReceiver';
|
||||||
import okDialog from './ui/okDialog';
|
import FileSender from './fileSender';
|
||||||
import copyDialog from './ui/copyDialog';
|
import copyDialog from './ui/copyDialog';
|
||||||
|
import faviconProgressbar from './ui/faviconProgressbar';
|
||||||
|
import okDialog from './ui/okDialog';
|
||||||
import shareDialog from './ui/shareDialog';
|
import shareDialog from './ui/shareDialog';
|
||||||
import signupDialog from './ui/signupDialog';
|
import signupDialog from './ui/signupDialog';
|
||||||
import surveyDialog from './ui/surveyDialog';
|
import surveyDialog from './ui/surveyDialog';
|
||||||
|
import { bytes, locale } from './utils';
|
||||||
|
import { copyToClipboard, delay, openLinksInNewTab, percent } from './utils';
|
||||||
|
|
||||||
export default function(state, emitter) {
|
export default function(state, emitter) {
|
||||||
let lastRender = 0;
|
let lastRender = 0;
|
||||||
@@ -29,6 +30,7 @@ export default function(state, emitter) {
|
|||||||
if (updateTitle) {
|
if (updateTitle) {
|
||||||
emitter.emit('DOMTitleChange', percent(state.transfer.progressRatio));
|
emitter.emit('DOMTitleChange', percent(state.transfer.progressRatio));
|
||||||
}
|
}
|
||||||
|
faviconProgressbar.updateFavicon(state.transfer.progressRatio);
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +39,7 @@ export default function(state, emitter) {
|
|||||||
document.addEventListener('focus', () => {
|
document.addEventListener('focus', () => {
|
||||||
updateTitle = false;
|
updateTitle = false;
|
||||||
emitter.emit('DOMTitleChange', 'Send');
|
emitter.emit('DOMTitleChange', 'Send');
|
||||||
|
faviconProgressbar.updateFavicon(0);
|
||||||
});
|
});
|
||||||
checkFiles();
|
checkFiles();
|
||||||
});
|
});
|
||||||
@@ -83,6 +86,7 @@ export default function(state, emitter) {
|
|||||||
|
|
||||||
emitter.on('cancel', () => {
|
emitter.on('cancel', () => {
|
||||||
state.transfer.cancel();
|
state.transfer.cancel();
|
||||||
|
faviconProgressbar.updateFavicon(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
emitter.on('addFiles', async ({ files }) => {
|
emitter.on('addFiles', async ({ files }) => {
|
||||||
@@ -161,6 +165,7 @@ export default function(state, emitter) {
|
|||||||
state.storage.totalUploads += 1;
|
state.storage.totalUploads += 1;
|
||||||
const duration = Date.now() - start;
|
const duration = Date.now() - start;
|
||||||
metrics.completedUpload(archive, duration);
|
metrics.completedUpload(archive, duration);
|
||||||
|
faviconProgressbar.updateFavicon(0);
|
||||||
|
|
||||||
state.storage.addFile(ownedFile);
|
state.storage.addFile(ownedFile);
|
||||||
// TODO integrate password into /upload request
|
// TODO integrate password into /upload request
|
||||||
@@ -264,6 +269,7 @@ export default function(state, emitter) {
|
|||||||
duration,
|
duration,
|
||||||
password_protected: file.requiresPassword
|
password_protected: file.requiresPassword
|
||||||
});
|
});
|
||||||
|
faviconProgressbar.updateFavicon(0);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.message === '0') {
|
if (err.message === '0') {
|
||||||
// download cancelled
|
// download cancelled
|
||||||
|
|||||||
1076
app/qrcode.js
Normal file
1076
app/qrcode.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -48,19 +48,36 @@ function password(state) {
|
|||||||
${state.translate('addPassword')}
|
${state.translate('addPassword')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<div class="relative inline-block my-1">
|
||||||
id="password-input"
|
<input
|
||||||
class="${state.archive.password
|
id="password-input"
|
||||||
? ''
|
class="${state.archive.password
|
||||||
: 'invisible'} border rounded focus:border-blue-60 leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80"
|
? ''
|
||||||
autocomplete="off"
|
: 'invisible'} border rounded focus:border-blue-60 leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80"
|
||||||
maxlength="${MAX_LENGTH}"
|
autocomplete="off"
|
||||||
type="password"
|
maxlength="${MAX_LENGTH}"
|
||||||
oninput="${inputChanged}"
|
type="password"
|
||||||
onfocus="${focused}"
|
oninput="${inputChanged}"
|
||||||
placeholder="${state.translate('unlockInputPlaceholder')}"
|
onfocus="${focused}"
|
||||||
value="${state.archive.password || ''}"
|
placeholder="${state.translate('unlockInputPlaceholder')}"
|
||||||
/>
|
value="${state.archive.password || ''}"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
id="password-preview-button"
|
||||||
|
type="button"
|
||||||
|
class="${state.archive.password
|
||||||
|
? ''
|
||||||
|
: 'invisible'} absolute top-0 right-0 w-8 h-8"
|
||||||
|
onclick="${onPasswordPreviewButtonclicked}"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="${assets.get('eye.svg')}"
|
||||||
|
width="22"
|
||||||
|
height="22"
|
||||||
|
class="m-auto mt-2"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<label
|
<label
|
||||||
id="password-msg"
|
id="password-msg"
|
||||||
for="password-input"
|
for="password-input"
|
||||||
@@ -69,15 +86,36 @@ function password(state) {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
function onPasswordPreviewButtonclicked(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const input = document.getElementById('password-input');
|
||||||
|
const eyeIcon = event.currentTarget.querySelector('img');
|
||||||
|
|
||||||
|
if (input.type === 'password') {
|
||||||
|
input.type = 'text';
|
||||||
|
eyeIcon.src = assets.get('eye-off.svg');
|
||||||
|
} else {
|
||||||
|
input.type = 'password';
|
||||||
|
eyeIcon.src = assets.get('eye.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
function togglePasswordInput(event) {
|
function togglePasswordInput(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const checked = event.target.checked;
|
const checked = event.target.checked;
|
||||||
const input = document.getElementById('password-input');
|
const input = document.getElementById('password-input');
|
||||||
|
const passwordPreviewButton = document.getElementById(
|
||||||
|
'password-preview-button'
|
||||||
|
);
|
||||||
if (checked) {
|
if (checked) {
|
||||||
input.classList.remove('invisible');
|
input.classList.remove('invisible');
|
||||||
|
passwordPreviewButton.classList.remove('invisible');
|
||||||
input.focus();
|
input.focus();
|
||||||
} else {
|
} else {
|
||||||
input.classList.add('invisible');
|
input.classList.add('invisible');
|
||||||
|
passwordPreviewButton.classList.add('invisible');
|
||||||
input.value = '';
|
input.value = '';
|
||||||
document.getElementById('password-msg').textContent = '';
|
document.getElementById('password-msg').textContent = '';
|
||||||
state.archive.password = null;
|
state.archive.password = null;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
const { copyToClipboard } = require('../utils');
|
const { copyToClipboard } = require('../utils');
|
||||||
|
const qr = require('./qr');
|
||||||
|
|
||||||
module.exports = function(name, url) {
|
module.exports = function(name, url) {
|
||||||
const dialog = function(state, emit, close) {
|
const dialog = function(state, emit, close) {
|
||||||
@@ -16,13 +17,23 @@ module.exports = function(name, url) {
|
|||||||
${state.translate('copyLinkDescription')} <br />
|
${state.translate('copyLinkDescription')} <br />
|
||||||
${name}
|
${name}
|
||||||
</p>
|
</p>
|
||||||
<input
|
<div class="flex flex-row items-center justify-center w-full">
|
||||||
type="text"
|
<input
|
||||||
id="share-url"
|
type="text"
|
||||||
class="w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
|
id="share-url"
|
||||||
value="${url}"
|
class="block w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
|
||||||
readonly="true"
|
value="${url}"
|
||||||
/>
|
readonly="true"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
id="qr-btn"
|
||||||
|
class="w-16 m-1 p-1"
|
||||||
|
onclick="${toggleQR}"
|
||||||
|
title="QR code"
|
||||||
|
>
|
||||||
|
${qr(url)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
class="btn rounded-lg w-full flex-shrink-0 focus:outline"
|
class="btn rounded-lg w-full flex-shrink-0 focus:outline"
|
||||||
onclick="${copy}"
|
onclick="${copy}"
|
||||||
@@ -40,6 +51,19 @@ module.exports = function(name, url) {
|
|||||||
</send-copy-dialog>
|
</send-copy-dialog>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
function toggleQR(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
const shareUrl = document.getElementById('share-url');
|
||||||
|
const qrBtn = document.getElementById('qr-btn');
|
||||||
|
if (shareUrl.classList.contains('hidden')) {
|
||||||
|
shareUrl.classList.replace('hidden', 'block');
|
||||||
|
qrBtn.classList.replace('w-48', 'w-16');
|
||||||
|
} else {
|
||||||
|
shareUrl.classList.replace('block', 'hidden');
|
||||||
|
qrBtn.classList.replace('w-16', 'w-48');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function copy(event) {
|
function copy(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
copyToClipboard(url);
|
copyToClipboard(url);
|
||||||
|
|||||||
41
app/ui/faviconProgressbar.js
Normal file
41
app/ui/faviconProgressbar.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
const { platform } = require('../utils');
|
||||||
|
const assets = require('../../common/assets');
|
||||||
|
|
||||||
|
const size = 32;
|
||||||
|
const loaderWidth = 5;
|
||||||
|
const loaderColor = '#0090ed';
|
||||||
|
|
||||||
|
function drawCircle(canvas, context, color, lineWidth, outerWidth, percent) {
|
||||||
|
canvas.width = canvas.height = outerWidth;
|
||||||
|
context.translate(outerWidth * 0.5, outerWidth * 0.5);
|
||||||
|
context.rotate(-Math.PI * 0.5);
|
||||||
|
const radius = (outerWidth - lineWidth) * 0.5;
|
||||||
|
context.beginPath();
|
||||||
|
context.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
|
||||||
|
context.strokeStyle = color;
|
||||||
|
context.lineCap = 'square';
|
||||||
|
context.lineWidth = lineWidth;
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawNewFavicon(progressRatio) {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
drawCircle(canvas, context, '#efefef', loaderWidth, size, 1);
|
||||||
|
drawCircle(canvas, context, loaderColor, loaderWidth, size, progressRatio);
|
||||||
|
return canvas.toDataURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.updateFavicon = function(progressRatio) {
|
||||||
|
if (platform() === 'web') {
|
||||||
|
const link = document.querySelector("link[rel='icon'][sizes='32x32']");
|
||||||
|
const progress = progressRatio * 100;
|
||||||
|
if (progress === 0 || progress === 100) {
|
||||||
|
link.type = 'image/png';
|
||||||
|
link.href = assets.get('favicon-32x32.png');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
link.href = drawNewFavicon(progressRatio);
|
||||||
|
}
|
||||||
|
};
|
||||||
10
app/ui/qr.js
Normal file
10
app/ui/qr.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
const raw = require('choo/html/raw');
|
||||||
|
const qrcode = require('../qrcode');
|
||||||
|
|
||||||
|
module.exports = function(url) {
|
||||||
|
const gen = qrcode(5, 'L');
|
||||||
|
gen.addData(url);
|
||||||
|
gen.make();
|
||||||
|
const qr = gen.createSvgTag({ scalable: true });
|
||||||
|
return raw(qr);
|
||||||
|
};
|
||||||
1
assets/eye-off.svg
Normal file
1
assets/eye-off.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#8795a1" d="M256.1 144.8c56.2 0 101.9 45.3 101.9 101.1 0 13.1-2.6 25.5-7.3 37l59.5 59c30.8-25.5 55-58.4 69.9-96-35.3-88.7-122.3-151.6-224.2-151.6-28.5 0-55.8 5.1-81.1 14.1l44 43.7c11.6-4.6 24.1-7.3 37.3-7.3zM52.4 89.7l46.5 46.1 9.4 9.3c-33.9 26-60.4 60.8-76.3 100.8 35.2 88.7 122.2 151.6 224.1 151.6 31.6 0 61.7-6.1 89.2-17l8.6 8.5 59.7 59 25.9-25.7L78.2 64 52.4 89.7zM165 201.4l31.6 31.3c-1 4.2-1.6 8.7-1.6 13.1 0 33.5 27.3 60.6 61.1 60.6 4.5 0 9-.6 13.2-1.6l31.6 31.3c-13.6 6.7-28.7 10.7-44.8 10.7-56.2 0-101.9-45.3-101.9-101.1 0-15.8 4.1-30.7 10.8-44.3zm87.8-15.7l64.2 63.7.4-3.2c0-33.5-27.3-60.6-61.1-60.6l-3.5.1z"/></svg>
|
||||||
|
After Width: | Height: | Size: 701 B |
1
assets/eye.svg
Normal file
1
assets/eye.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#8795a1" d="M256 105c-101.8 0-188.4 62.4-224 151 35.6 88.6 122.2 151 224 151s188.4-62.4 224-151c-35.6-88.6-122.2-151-224-151zm0 251.7c-56 0-101.8-45.3-101.8-100.7S200 155.3 256 155.3 357.8 200.6 357.8 256 312 356.7 256 356.7zm0-161.1c-33.6 0-61.1 27.2-61.1 60.4s27.5 60.4 61.1 60.4 61.1-27.2 61.1-60.4-27.5-60.4-61.1-60.4z"/></svg>
|
||||||
|
After Width: | Height: | Size: 406 B |
@@ -1,2 +1,2 @@
|
|||||||
# flod as main contact for string changes
|
# timvisee as main contact for string changes
|
||||||
public/locales/en-US/*.ftl @flodolo
|
public/locales/en-US/*.ftl @timvisee
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# File Encryption
|
# File Encryption
|
||||||
|
|
||||||
Send use 128-bit AES-GCM encryption via the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) to encrypt files in the browser before uploading them to the server. The code is in [app/keychain.js](../app/keychain.js).
|
Send uses 128-bit AES-GCM encryption via the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) to encrypt files in the browser before uploading them to the server. The code is in [app/keychain.js](../app/keychain.js).
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
|
|||||||
2043
package-lock.json
generated
2043
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "send",
|
"name": "send",
|
||||||
"description": "File Sharing Experiment",
|
"description": "File Sharing Experiment",
|
||||||
"version": "3.2.0",
|
"version": "3.3.2",
|
||||||
"author": "Mozilla (https://mozilla.org)",
|
"author": "Mozilla (https://mozilla.org)",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Tim Visee <3a4fb3964f@sinenomine.email> (https://timvisee.com)"
|
"Tim Visee <3a4fb3964f@sinenomine.email> (https://timvisee.com)"
|
||||||
@@ -64,28 +64,28 @@
|
|||||||
"node": "^12.16.3"
|
"node": "^12.16.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.1",
|
"@babel/core": "^7.12.3",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||||
"@babel/preset-env": "^7.12.1",
|
"@babel/preset-env": "^7.12.1",
|
||||||
"@dannycoates/webcrypto-liner": "^0.1.37",
|
"@dannycoates/webcrypto-liner": "^0.1.37",
|
||||||
"@fullhuman/postcss-purgecss": "^1.3.0",
|
"@fullhuman/postcss-purgecss": "^1.3.0",
|
||||||
"@mattiasbuelens/web-streams-polyfill": "0.2.1",
|
"@mattiasbuelens/web-streams-polyfill": "0.2.1",
|
||||||
"@sentry/browser": "^5.26.0",
|
"@sentry/browser": "^5.27.4",
|
||||||
"asmcrypto.js": "^0.22.0",
|
"asmcrypto.js": "^0.22.0",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.2.1",
|
||||||
"babel-plugin-istanbul": "^5.2.0",
|
"babel-plugin-istanbul": "^5.2.0",
|
||||||
"base64-js": "^1.3.1",
|
"base64-js": "^1.5.1",
|
||||||
"content-disposition": "^0.5.3",
|
"content-disposition": "^0.5.3",
|
||||||
"copy-webpack-plugin": "^5.1.2",
|
"copy-webpack-plugin": "^5.1.2",
|
||||||
"core-js": "^3.4.0",
|
"core-js": "^3.7.0",
|
||||||
"crc": "^3.8.0",
|
"crc": "^3.8.0",
|
||||||
"cross-env": "^6.0.3",
|
"cross-env": "^6.0.3",
|
||||||
"css-loader": "^3.6.0",
|
"css-loader": "^3.6.0",
|
||||||
"css-mqpacker": "^7.0.0",
|
"css-mqpacker": "^7.0.0",
|
||||||
"cssnano": "^4.1.10",
|
"cssnano": "^4.1.10",
|
||||||
"eslint": "^6.6.0",
|
"eslint": "^6.6.0",
|
||||||
"eslint-config-prettier": "^6.12.0",
|
"eslint-config-prettier": "^6.15.0",
|
||||||
"eslint-plugin-mocha": "^6.2.1",
|
"eslint-plugin-mocha": "^6.2.1",
|
||||||
"eslint-plugin-node": "^10.0.0",
|
"eslint-plugin-node": "^10.0.0",
|
||||||
"eslint-plugin-security": "^1.4.0",
|
"eslint-plugin-security": "^1.4.0",
|
||||||
@@ -118,12 +118,12 @@
|
|||||||
"script-loader": "^0.7.2",
|
"script-loader": "^0.7.2",
|
||||||
"sinon": "^7.5.0",
|
"sinon": "^7.5.0",
|
||||||
"string-hash": "^1.1.3",
|
"string-hash": "^1.1.3",
|
||||||
"stylelint": "^11.1.1",
|
"stylelint": "^13.7.2",
|
||||||
"stylelint-config-standard": "^19.0.0",
|
"stylelint-config-standard": "^19.0.0",
|
||||||
"stylelint-no-unsupported-browser-features": "^3.0.2",
|
"stylelint-no-unsupported-browser-features": "^4.1.4",
|
||||||
"svgo": "^1.3.2",
|
"svgo": "^1.3.2",
|
||||||
"svgo-loader": "^2.2.1",
|
"svgo-loader": "^2.2.1",
|
||||||
"tailwindcss": "^1.9.2",
|
"tailwindcss": "^1.9.6",
|
||||||
"val-loader": "^1.1.1",
|
"val-loader": "^1.1.1",
|
||||||
"webpack": "4.38.0",
|
"webpack": "4.38.0",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^3.3.12",
|
||||||
@@ -136,9 +136,9 @@
|
|||||||
"@dannycoates/express-ws": "^5.0.3",
|
"@dannycoates/express-ws": "^5.0.3",
|
||||||
"@fluent/bundle": "^0.13.0",
|
"@fluent/bundle": "^0.13.0",
|
||||||
"@fluent/langneg": "^0.3.0",
|
"@fluent/langneg": "^0.3.0",
|
||||||
"@google-cloud/storage": "^5.1.2",
|
"@google-cloud/storage": "^5.5.0",
|
||||||
"@sentry/node": "^5.26.0",
|
"@sentry/node": "^5.27.4",
|
||||||
"aws-sdk": "^2.772.0",
|
"aws-sdk": "^2.792.0",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"choo": "^7.0.0",
|
"choo": "^7.0.0",
|
||||||
"cldr-core": "^35.1.0",
|
"cldr-core": "^35.1.0",
|
||||||
|
|||||||
@@ -36,19 +36,10 @@ module.exports = function(app) {
|
|||||||
defaultSrc: ["'self'"],
|
defaultSrc: ["'self'"],
|
||||||
connectSrc: [
|
connectSrc: [
|
||||||
"'self'",
|
"'self'",
|
||||||
'wss://*.dev.lcip.org',
|
|
||||||
'wss://*.send.nonprod.cloudops.mozgcp.net',
|
|
||||||
config.base_url.replace(/^https:\/\//, 'wss://'),
|
config.base_url.replace(/^https:\/\//, 'wss://'),
|
||||||
'https://*.dev.lcip.org',
|
|
||||||
'https://accounts.firefox.com',
|
|
||||||
'https://*.accounts.firefox.com',
|
|
||||||
'https://sentry.prod.mozaws.net'
|
|
||||||
],
|
],
|
||||||
imgSrc: [
|
imgSrc: [
|
||||||
"'self'",
|
"'self'",
|
||||||
'https://*.dev.lcip.org',
|
|
||||||
'https://firefoxusercontent.com',
|
|
||||||
'https://secure.gravatar.com'
|
|
||||||
],
|
],
|
||||||
scriptSrc: [
|
scriptSrc: [
|
||||||
"'self'",
|
"'self'",
|
||||||
@@ -66,18 +57,6 @@ module.exports = function(app) {
|
|||||||
csp.directives.connectSrc.push(
|
csp.directives.connectSrc.push(
|
||||||
config.base_url.replace(/^https:\/\//, 'wss://')
|
config.base_url.replace(/^https:\/\//, 'wss://')
|
||||||
);
|
);
|
||||||
if (config.fxa_csp_oauth_url != '') {
|
|
||||||
csp.directives.connectSrc.push(config.fxa_csp_oauth_url);
|
|
||||||
}
|
|
||||||
if (config.fxa_csp_content_url != '') {
|
|
||||||
csp.directives.connectSrc.push(config.fxa_csp_content_url);
|
|
||||||
}
|
|
||||||
if (config.fxa_csp_profile_url != '') {
|
|
||||||
csp.directives.connectSrc.push(config.fxa_csp_profile_url);
|
|
||||||
}
|
|
||||||
if (config.fxa_csp_profileimage_url != '') {
|
|
||||||
csp.directives.imgSrc.push(config.fxa_csp_profileimage_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
app.use(helmet.contentSecurityPolicy(csp));
|
app.use(helmet.contentSecurityPolicy(csp));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user